UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN DESARROLLO DE SISTEMA COFIDI WEB SOBRE PLATAFORMA JAVA

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN DESARROLLO DE SISTEMA COFIDI WEB SOBRE PLATAFORMA JAVA. Trabajo

4 downloads 18 Views 2MB Size

Recommend Stories


UNIVERSIDAD NACIONAL AUTONOMA DE MEXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLAN
UNIVERSIDAD NACIONAL AUTONOMA DE MEXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLAN TRABAJO PROFESIONAL PARA OBTENER EL TITULO DE LICENCIADO DE ADMIN

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN
UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN “COMPRAS Y ABASTECIMIENTO ESTRATÉGICO EN UNA EMPRESA QUE FABRICA,

UNIVERSIDAD NACIONAL AUTONOMA DE MEXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLAN
UNIVERSIDAD NACIONAL AUTONOMA DE MEXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLAN OBLIGACIONES DE UNA PERSONA FISICA QUE TRIBUTA BAJO EL REGIMEN IN

FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN
FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN INTRODUCCIÓN La esencia de la Facultad de Estudios Superiores Cuautitlán radica en los principios de la Un

DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN
UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN “EL PROCESO CONTABLE Y DESARROLLO DE LAS ACTIVIDADES DE UN DES

UNIVERSIDAD NACIONAL SISTEMA DE ESTUDIOS DE POSGRADO
UNIVERSIDAD NACIONAL SISTEMA DE ESTUDIOS DE POSGRADO El Convenio Bilateral de Desarrollo Sostenible entre Costa Rica y el Reino de los Países Bajos :

Story Transcript

UNIVERSIDAD NACIONAL AUTÓNOMA DE MÉXICO

FACULTAD DE ESTUDIOS SUPERIORES CUAUTITLÁN

DESARROLLO DE SISTEMA COFIDI WEB SOBRE PLATAFORMA JAVA.

Trabajo profesional QUE PARA OBTENER EL TÍTULO DE: LICENCIADO EN INFORMÁTICA

PRESENTA: MARLENE JOSSUE MUGA AVILA

Asesor: M. C.C. María Araceli Nivón Zaghi Cuautitlán Izcalli, edo. De Méx. 2013

DEDICATORIAS Antes que nada le doy gracias a Dios por permitirme concluir mis estudios y darme la fuerza para continuar superándome.

A mi madre dedico este trabajo, porque ella es el motor que me impulsa a seguir adelante, porque siempre estuvo dispuesta a apoyarme, escucharme, cuidarme y por ser quien es, el ser que más quiero en la sobre la faz de la tierra.

A mi familia le doy muchas gracias porque estuvieron en momentos muy difíciles de mi vida y sin su apoyo tal vez no se hubiera podido fincar las bases para llegar a este punto.

A mis amigos porque a base de sus consejos sin rodeos, de sus bromas y del abrazo cálido me han brindando momentos muy bonitos en mi vida.

A la UNAM por brindarme la oportunidad de estudiar en una escuela de calidad a nivel mundial.

A mi asesora la cual admiro en gran medida y que con paciencia me ha guiado no solo en este trabajo, si no en mi carrera muchas gracias.

A la empresa que me brindo la oportunidad de desarrollarme profesionalmente ATEB SERVICIOS.

Índice 1. Introducción

6

2. Conceptos

7

2.1. La Facturación Electrónica 2.1.1. Características, Ventajas y Beneficios de la Factura Electrónica 2.1.2. Tipos de Facturación Electrónica 2.1.2.1. CFD 2.1.2.2. CFDI 2.1.3. Un PAC de CFDI 2.1.3.1. Obligaciones del PAC

2.2. Plataformas de Desarrollo

7 7 8 8 8 9 9

11

2.2.1. JAVA 2.2.2. Framework STRUTS 2.2.2.1. ACTION Servlet 2.2.2.2. ACTION 2.2.2.3. ACTION Form 2.2.2.4. ACTION Mapping 2.2.2.5. ACTION Forward 2.2.3. HIBERNATE 2.2.4. ¿Qué son los WEB SERVICES? 2.2.5. Concepto de SQL SERVER

11 11 12 12 13 13 13 14 14 15

3. Descripción del trabajo profesional

16

3.1. Historia Profesional

16

3.2. Descripción de ATEB Servicios

17

3.2.1. Misión 3.2.2. Visión 3.2.3. Valores 3.2.4. Información comercial 3.2.5. Estructura de ATEB Servicios 3.2.6. Funciones como programador JAVA dentro de la Gerencia de Desarrollo de ATEB Servicios. 3.2.5.1. Flujo del Proyecto

17 17 17 18 19 20 20

3.3. Conexiones de COFIDI WEB

21

3.4. Desarrollados

24

3.4.1. Módulo XLSS 3.4.2. Aplicación Resultado de Timbrado 3.4.3. COFIDI DELPHI 3.4.3.1. Elementos del Menú Contextual 3.4.3.1.1. Elemento PROBLEM INVOICE 3.4.3.1.1.1. Función cancelada( ) 3.4.3.1.1.2. Función Aprobal( ) 3.4.1.2. Elemento Archivos Adjuntos 3.4.3.2. Reportes DELPHI

24 27 29 30 30 32 35 37 38

4. Discusión y Análisis

41

5. Recomendaciones

42

6. Conclusión

43

Bibliografía

44

ANEXO A. Módulo XLSS

45

ANEXO B. Aplicación Resultado de Timbrado

48

ANEXO C. Elementos del Menú Contextual COFIDI DELPHI

53

Glosario

76

1. Introducción ATEB Servicios es una empresa dedicada a proveer soluciones referentes al comercio electrónico así como los conocimientos y tecnología E-Commerce necesaria para que las empresas tengan una ventaja competitiva con sus clientes y proveedores. ATEB Servicios, fue una de las primeras empresas que inicio con la facturación electrónica en el año 2005 debido a la disposición del SAT (Secretaria de Administración Tributaria) decretada en octubre del 2004. Ante ésta disposición nace la figura del Proveedor Autorizado de Certificación (PAC) siendo ATEB uno de los que cumplen con los requerimientos e infraestructura necesaria para recibir ésta nominación por parte del SAT. La empresa tiene sucursales en Distrito Federal, Puebla, Jalisco, Monterrey y Guatemala. Algunos de sus clientes son Chrysler de México, VW de México, Grupo CIE, NISSAN Mexica, DHL, GRUPO POEZA, 3M de México, GRUPO BOCAR, EATON, CALSONIC KANSEI, TUM (Trans. Unidos Mexicanos), PANALPINA, GRUPO VALUE, VENDOR, VOLVO, CONTINENTAL TIRE WYETH, JANSSEN CILAG, GRUPO AXO, DULCES DE LA ROSA, SIMEC, TRACSA, HEINZ por mencionar algunos. Cuenta con las siguientes áreas: Oficial de Seguridad de la Información (ISO), Gerencia de Calidad, Gerencia de ventas, Gerencia de Administración y Recursos Humanos, Gerencia de Desarrollo y Gerencia de Implementación y Soporte Técnico. La Gerencia de Desarrollo se divide en dos grupos uno es el encargado de generar aplicaciones .NET que van encaminadas hacia el sistema COFIDI Windows, el segundo grupo es encargado de programar los entornos WEB basados en la plataforma JAVA, tal es el caso del sistema COFIDI WEB. La principal función de los sistemas COFIDI Windows y COFIDI WEB es enviar y recibir facturas electrónicas, generar adendas y reglas de negocio, además de que cuentan con formatos de impresión modificables, comunicaciones integradas en el software y no requieren certificación del SAT (Integrador de soluciones). En el presente informe se realiza una descripción del trabajo profesional realizado en el área de desarrollo de sistemas WEB, tomando como base el sistema COFIDI WEB, del cual se desprenden diversas versiones para cada cliente. Para el desarrollo de este sistema se tuvo como líder de proyecto al Ing. Juan Manuel Olea Méndez.

Mi desempeño en ATEB Servicios fue como desarrollador JAVA,

encargándome de programar, modificar y hacer pruebas al sistema CODIFI WEB.

6

2. Conceptos

2.1. La Facturación Electrónica

La Facturación Electrónica es un mecanismo de comprobación fiscal que se basa en el aprovechamiento de medios electrónicos para la generación, procesamiento, transmisión y resguardo de los documentos fiscales de manera digital. A partir de enero de 2011 se inició paulatinamente su uso generalizado con base en la reforma al artículo 29 del Código Fiscal de la Federación. Con ello, los contribuyentes expiden documentos digitales como comprobantes por las actividades que realizan. (SERVICIO DE ADMINISTRACIÓN TRIBUTARIA, 2011)

2.1.1. Características, Ventajas y Beneficios de la Factura Electrónica

Características 

Integra: Garantiza que la información contenida queda protegida y no puede ser manipulada o modificada.



Autentifica: Permite verificar la identidad del emisor y el receptor de la Factura Electrónica.



Verificable: La persona que emita una Factura Electrónica, no podrá negar haberlo generado.



Única: Garantiza no ser violada, falsificada o repetida al validar el folio, número de aprobación y vigencia del certificado de sello digital con el que fue sellada, puede validarse contra el informe mensual.

Ventajas 

Agiliza la conciliación de la información contable.



Simplifica el proceso de generación de comprobantes para efectos fiscales.



A mayor proporción de Facturas emitidas electrónicamente, mayor ahorro.



La Factura Electrónica puede ser vista rápidamente desde cualquier navegador para internet.

7



El almacenamiento de los comprobantes para el emisor es de manera electrónica.



El almacenamiento de las Facturas Electrónicas para el receptor es de manera electrónica o en papel según lo solicite.



Integración automática y segura a su contabilidad.

Beneficios 

Mejora el servicio al cliente.



Reduce costos y errores en el proceso de generación, captura, entrega y almacenamiento.



Mayor control documental. (SERVICIO DE ADMINISTRACIÓN TRIBUTARIA, 2011)

2.1.2. Tipos de Facturación Electrónica

2.1.2.1. CFD

CFD1 es un mecanismo de comprobación fiscal de ingresos, egresos y propiedad de mercancías en traslado por medios electrónicos, cuya particularidad es el uso de las tecnologías de la información para la generación, procesamiento, transmisión y resguardo de los documentos fiscales de manera digital. Las Facturas Electrónicas son documentos electrónicos que permiten comprobar las operaciones realizadas entre los contribuyentes, bajo estándares tecnológicos y de seguridad internacionalmente reconocidos.

2.1.2.2. CFDI

CFDI2 es un archivo electrónico de formato y extensión .XML vigente a partir de Enero de 2011, el cuál debe ser enviado a un PAC3 para que valide el comprobante, le asigne un folio y sea incorporado el sello digital del SAT4 antes de ser entregado al cliente. A este proceso se le conoce como: Timbrado Fiscal Digital. El archivo electrónico debe cumplir con los lineamientos de los rubros II.A, II.B y II.C del Anexo 20 de la RMF 5, sin embargo, también pueden ser impresos en papel cumpliendo los requisitos que se indican en la RMF. (Facturador Electrónico, 2010)

1 CFD. Comprobante Fiscal Digital, 2 CFDI. Comprobante Fiscal Digital por Internet, 3 PAC. Proveedor Autorizado de Certificación, 4 SAT. Servicio de Administración Tributaria, 5 RMF. Resolución Miscelánea Fiscal

8

2.1.3. Un PAC de CFDI

Es aquella persona moral que cuenta con autorización del SAT para validar los CFDI generados por los contribuyentes, asignarles el folio e incorporarles el sello digital del SAT. Asimismo, tienen como obligación, enviar al SAT copia de los CFDI que validen de sus clientes. 2.1.3.1. Obligaciones del PAC

Los proveedores autorizados de certificación de CFDI deberán cumplir las siguientes obligaciones: 

Guardar absoluta reserva de la información de los CFDI que certifiquen a los contribuyentes, en términos de la Ley Federal de Protección de Datos Personales en Posesión de los Particulares, publicada en el DOF6 el 5 de julio de 2010, dicha reserva también debe estar estipulada por escrito como una obligación a cargo del proveedor.



Devolver al contribuyente el CFDI previamente validado conforme a lo que establecen los artículos 29 y 29-A del CFF7, así como los señalados en las demás disposiciones aplicables, con folio asignado y con el sello digital del SAT.



Enviar al SAT de manera inmediata copia de los CFDI una vez que hayan sido certificados. Dicho envío se realizará con las características y especificaciones técnicas que le proporcionó el SAT al momento de obtener la autorización.



Tener en todo momento a disposición del SAT la posibilidad de realizar el acceso remoto o local a las bases de datos en donde se resguarde la información y copias de los CFDI que hayan certificado en los últimos tres meses.



Proporcionar al contribuyente emisor una herramienta para consulta del detalle de sus CFDI certificados, esta herramienta deberá cumplir con las especificaciones señaladas en el apartado correspondiente ubicado en la página de Internet del SAT.



Conservar los CFDI certificados, por un término de tres meses, en un medio electrónico, óptico o de cualquier tecnología, aun cuando no subsista la relación jurídica al amparo de la cual se certificaron los CFDI.



Administrar, controlar y resguardar a través de su sistema certificador de CFDI, los CSD8 que el SAT le proporcione para realizar su función.



Comunicar por escrito o vía correo electrónico a sus clientes en caso de que se suspenda temporal o definitivamente sus servicios, y dar al SAT, en su caso,

9 6 DOF. Diario Oficial de la Federación, 7 CFF. Código Fiscal de la Federación, 8CSD. Certificado de Sello Digital

―Aviso de liquidación, concurso mercantil o acuerdo de extinción jurídica de la sociedad autorizada para operar como Proveedor de certificación de CFDI‖ En el caso del aviso a sus clientes, este deberá realizarse con treinta días hábiles de anticipación en caso de suspensión temporal o definitiva de operaciones. 

Presentar el ―Aviso electrónico de liquidación, concurso mercantil o acuerdo de extinción jurídica de la sociedad autorizada para operar como Proveedor de Certificación de CFDI‖, cuando el proveedor entre en proceso de liquidación, concurso mercantil o su órgano de dirección haya tomado acuerdo de extinción de la sociedad, según sea el caso, dentro del término de 72 horas o antes de que concluya el proceso de liquidación, concurso mercantil o extinción jurídica de la sociedad, lo que ocurra primero, el proveedor de certificación de CFDI deberá entregar al SAT la copia de los CFDI que haya certificado y que aún esté pendiente de dicho envió.



Validar que el CFDI que le fue remitido cumpla con lo siguiente: 

Que el periodo de tiempo entre la fecha de envió para certificación del documento y la fecha en la que se reciba el mismo por el proveedor de certificación no exceda de 72 horas.



Que el documento no haya sido previamente certificado por el propio proveedor de certificación.



Que el CSD del contribuyente emisor, con el que se selló el documento haya estado vigente en la fecha de generación del documento enviado y no haya sido cancelado.



Que el CSD con el que se selló el documento corresponda al contribuyente que aparece como emisor del CFDI, y que el sello digital corresponda al documento enviado.



Que el documento cumpla con la especificación técnica del Anexo 20.



Si el CFDI cumple con las validaciones anteriores, el proveedor de certificación de CFDI dará respuesta al contribuyente incorporando el complemento que integre los siguientes datos: 

Folio asignado por el SAT.



Fecha y hora de certificación.



Número de serie del certificado digital del SAT con el que se realizó el sellado.



Sello digital del SAT. 10

El CFDI se considera expedido cuando una vez generado y sellado con el CSD del contribuyente es enviado para su certificación al proveedor autorizado para el sello por parte del SAT. Los contribuyentes emisores de CFDI, para efectuar la cancelación de los mismos, deberán hacerlo con su CSD, a través del servicio para consultar, cancelar y recuperar

Facturas

Electrónicas

(CFDI).

(SERVICIO

DE

ADMINISTRACIÓN

TRIBUTARIA, 2011)

2.2. Plataformas de Desarrollo

2.2.1. JAVA

Es un lenguaje de programación y la primera plataforma informática creada por Sun Microsystems en 1995. Es la tecnología subyacente que permite el uso de programas punteros, como herramientas, juegos y aplicaciones de negocios. Java se ejecuta en más de 850 millones de computadoras personales de todo el mundo y en miles de millones de dispositivos, como dispositivos móviles y aparatos de televisión. (Oracle Corporation, 2009)

2.2.2. Framework STRUTS

Struts es un framework o marco de trabajo desarrollado por el grupo Apache,

que

proporciona un conjunto de utilidades cuyo objetivo es facilitar y optimizar los desarrollos de aplicaciones Web tecnología J2EE, siguiendo el patrón MVC. El marco de trabajo Struts está constituido por los siguientes elementos o componentes: 

Archivos de configuración



El API de Struts



Librerías de acciones JSP

La estructura del documento de configuración es:

Struts

11



2.2.2.1. ACTION Servlet

Es un objeto que constituye el punto de entrada de la aplicación, recibiendo todas las peticiones HTTP que llegan de la capa cliente. Se trata básicamente de un servlet HTTP cuya clase hereda a HttpServlet. El objeto ACTIONServlet lleva a cabo la siguiente funcionalidad dentro de una aplicación: cada vez que recibe una petición desde el cliente y a fin de determinar la operación a realizar, extrae la ultima URL y la contrasta con la información contenida en el archivo de configuración struts-config.XML, a partir de la cual, el objeto lleva a cabo la instanciación del JavaBean asociado a la acción, lo rellena con los datos procedentes del formulario cliente y deposita la instancia en el contexto correspondiente, pasando a continuación el control de la petición al objeto ACTION encargado de procesarla.

2.2.2.2. ACTION

Como se acaba de comentar, los objetos ACTION son los responsables de procesar los distintos tipos de peticiones que llegan a la aplicación. El principal método con que esta clase cuenta es execute (), método que será invocado por ACTIONServlet al transferir la petición al objeto. Así pues, por cada tipo de petición que se vaya a controlar, el programador deberá definir una subclase de ACTION y sobrescribir el método execute (), incluyendo en él las instrucciones requeridas para el tratamiento de la petición, tales como llamadas a los métodos de la lógica de negocio implementada en el modelo o la transferencia de resultados a las vistas para su presentación.

12

2.2.2.3. ACTION Form

Los objetos ACTION Form son un tipo especial de JavaBean que facilita el transporte de datos entre capas de la aplicación. Son utilizados por ACTIONServlet para capturar los datos procedentes de un formulario XHTML y enviárselos al objeto ACTION correspondiente, todo ello sin recurrir a los incómodos request.getParameter(). Para ello el programador deberá extender esta clase y proporcionar los datos miembros necesarios para el almacenamiento de los datos, así como los correspondientes métodos set/get que den acceso a los mismos.

2.2.2.4. ACTION Mapping

ACTION Mapping. Un objeto de tipo ACTIONMapping representa una asociación entre una petición y el objeto ACTION que la tiene que procesar. Contiene información sobre el path o tipo de URL que provoca la ejecución de la acción, así como de las posibles vistas que se pueden representar al cliente tas su procesamiento. Cuando el controlador ACTIONServlet invoca el método execute () de un objeto ACTION para el procesamiento de una petición, proporciona como parámetro un objeto ACTIONMapping con la información asociada a la misma, pudiéndose hacer uso de sus métodos para encaminar al usuario a cualquiera de las vistas asociadas al objeto una vez que la petición ha sido procesada.

2.2.2.5. ACTION Forward

ACTION Forward. Como ya mencionamos al hablar de las ventajas de Struts. Las aplicaciones que utilizan este framework trabajan con direcciones virtuales en vez de reales. Las direcciones virtuales, más conocidas en Struts como forwards; son manejadas desde código a través de objetos ACTIONForward. La clase ACTIONForward encapsula los detalles sobre la localización de un recurso, de modo que cada vez que se quiera transferir una petición desde código o re direccionar al usuario a una determinada página se hará utilizando objetos ACTIONForward. (Sierra, 2008)

13

2.2.3. HIBERNATE

Hibernate es una herramienta para la plataforma Java que facilita el mapeo de atributos entre una base de datos relacional y el modelo de objetos de una aplicación, mediante archivos declarativos (.XML) que permiten establecer estas relaciones. Hibernate es una herramienta ORM (Object Role Modeling) completa que ha conseguido en un tiempo record una excelente reputación en la comunidad de desarrollo posicionándose claramente como el producto OpenSource líder en este campo. (Unife, 2012)

2.2.4. ¿Qué son los WEB SERVICES?

Web Services son la auto-descripción y aplicaciones modulares de negocios que exponen la lógica de negocio como servicios a través de internet por medio de interfaces programables y el uso de protocolos de Internet con el fin de proporcionar formas de buscar, suscribirse, e invocar a esos servicios. Basados sobre el estándar .XML, los web services pueden ser desarrollados con una imprecisión

en los componentes de la aplicación utilizando cualquier lenguaje de

programación, cualquier protocolo o cualquier plataforma. (Nagappan, 2003) Extensible Markup Language(.XML) es un lenguaje muy simple, pero estricto que juega un papel fundamental en el intercambio de una gran variedad de datos. Es un lenguaje muy similar a HTML pero su función principal es describir datos y no mostrarlos como es el caso de HTML. .XML es un formato que permite la lectura de datos a través de diferentes aplicaciones. (Gidon, 2012) En él núcleo de los servicios Web se encuentra el protocolo simple de acceso a objetos (SOAP), que proporciona un mecanismo estándar de empaquetar mensajes. SOAP es un estándar para un ligero .XML-base protocoló mensajería. Es usado como el protocoló mensajero para el transporte, con reunión de varios protocolos de internet como HTTP, SMTP, FTP. El lenguaje de descripción de servicios Web (WSDL, Web Service Description Language) es un dialecto basado en .XML sobre el esquema que describe un servicio Web. Un documento WSDL proporciona la información necesaria al cliente para interaccionar con el servicio Web. WSDL es extensible y se puede utilizar para describir, prácticamente,

14

cualquier servicio de red, incluyendo SOAP sobre HTTP e incluso protocolos que no se basan en .XML como DCOM sobre UDP. (Scott, 2002)

2.2.5. Concepto de SQL SERVER

SQL Server es un conjunto de objetos eficientemente almacenados. Los objetos donde se almacena la información se denominan tablas, y éstas a su vez están compuestas de filas y columnas. En el centro de SQL Server está el motor de SQL Server, el cuál procesa los comandos de la base de datos. Los procesos se ejecutan dentro del sistema operativo y entienden únicamente de conexiones y de sentencias SQL. Transact-SQL es el lenguaje que utiliza SQL Server para poder enviar peticiones tanto de consultas, inserciones, modificaciones, y de borrado a las tablas, así como otras peticiones que el usuario necesite sobre los datos. En definitiva, es un lenguaje que utiliza SQL Server para poder gestionar los datos que contienen las tablas. El lenguaje estándar SQL (Structured Query Language) se emplea para los sistemas de bases de datos relacionales RDBMS (Relational Database Management System), es el estándar ANSI (American National Standards Institute). También es utilizado por otros sistemas como: Oracle, Access, Sybase, etc. Net-Library: Es el componente que controla las conexiones de diferentes protocolos y redes. Habilita SQL Server para escuchar a múltiples protocolos al mismo tiempo. Se puede configurar el servidor fácilmente para escuchar múltiples protocolos, empleando utilidades de red del servidor bajo SQL Server. SQL Server se encarga de administrar bases de datos relacionales basadas en la arquitectura Cliente / Servidor (RDBMS: Relational Database Management System). SQL Server utiliza la arquitectura Cliente / Servidor para coordinar el trabajo entre el equipo cliente y el equipo servidor. Dependiendo del tipo de aplicación que se quiera programar dependerá la repartición de la carga de trabajo entre el cliente y el servidor. El equipo cliente se suele encargar de la parte lógica y de mostrar la información al usuario que realiza una petición. El equipo servidor SQL Server, se encarga de administrar la base de datos, de gestionar los recursos del servidor. (CPU, memoria, etc.), y por supuesto de resolver y devolver en forma de solución la petición realizada por el cliente. (Forma Select, 2008)

15

3. Descripción del trabajo profesional 3.1. Historia Profesional

En la licenciatura en Informática tuve materias referentes a programación web pero en los últimos semestres de esta en la materia de Seminario de Multimedia II, se me impartió programación orientada a objetos y el lenguaje de programación que utilizamos era java, el cual me pareció muy interesante y completo ya que muchas aplicaciones lo utilizan, esto al concluir mis estudios me llevo a buscar trabajo como becario java en una consultoría que se llama EASYWEST situada por el metro Toreo, en si mis conocimientos en JAVA eran muy limitados pero esta empresa se encargo de prepararme más en este lenguaje pero enfocado a lo web así como el uso del framework Struts 2. Una vez que concluí mi estancia en EASYWEST que fue de un periodo de tres meses, busque trabajo de programador JAVA pero nivel junior

y en Internet encontré una

empresa llamada ATEB Servicios que solicitaba programadores JAVA nivel entrante mande mi currículo y concerté una cita para el día siguiente. Ya estando en la entrevista me hicieron preguntas referentes a mi estado civil, edad, nivel de estudios, promedio, nivel de inglés así como que conocimientos tenía en JAVA y qué clase de programas había desarrollado en este lenguaje así como cuánto tiempo tenía programando en este, me hicieron un examen escrito donde todas las preguntas eran referentes a struts, xslt y hibérnate las cuales en su mayoría estuvieron correctas ya que en mi anterior empleo había trabajado con struts y xslt sin embargo desconocía en su totalidad el framework hibérnate, ya que presente un buen examen el arquitecto de proyecto de la gerencia de desarrollo el Ing. Juan Manuel Olea Méndez me entrevisto y me hizo la observación de que casi todo el examen estaba correcto, pero que lo referente a hibérnate no, a lo cual yo conteste con sinceridad que desconocía ese framework, sin embargo el decidió darme la oportunidad de integrarme en su equipo de trabajo. Una vez dentro la primera tarea que se me asigno fue la creación del módulo XLSS para COFIDI WEB el cual es explicado más a detalle en el presente trabajo, y así sucesivamente con el paso del tiempo se me asignaron otros proyectos más grandes como el programar diversos módulos para el área de recepción de comprobantes fiscales de la empresa Delphi o incluso pequeñas aplicaciones que apoyan al área de soporte como es la aplicación Resultado de timbrado.

16

3.2. Descripción de ATEB Servicios Fundada en junio del 2000 por consultores que cuentan con más de 20 años de experiencia en comunicaciones B2B; en plataformas de computo PDA,PC, AS/400, UNIX, AIX, SUN Solaris, HP900, NT, mainframe además de desarrollos e integraciones con diversos ERP’S como: Mfg-Pro, XPPS, People Soft(JDE), infor, BPCS, MAPICS, SAP, SAE, Control 2000, Retail Pro, Sistemas Propietarios, etc.; a su vez desarrollaron e implementaron solución de Intercambio Electrónico de Datos (EDI) desde hace más de 10 años.

3.2.1. Misión

Es entregar Proyectos Integrales a precios competitivos con excelente nivel de servicio a todos sus clientes ofreciendo una mejor calidad de vida a sus colaboradores, siendo socialmente responsable y otorgando utilidades atractivas a sus accionistas.

3.2.2. Visión

Es ser la mejor opción en el mercado ofreciendo herramientas rentables y de vanguardia en el Continente Americano mediante la creación, implementación y mantenimiento de las mismas, buscando alianzas estratégicas para colaborar en otras latitudes.

3.2.3. Valores

Algunos de los valores con que están comprometidos son: 

Honestidad:

No engañan a sus socios comerciales ni a su equipo de trabajo, no contribuyen con actos delictivos, por lo que son íntegros y responsables en todo momento. 

Servicio:

Brindan servicio cumpliendo los estándares de calidad de sus clientes, e incluso os rebasan en tiempo y forma, siempre resolviendo sus requerimientos. 

Capacidad:

17

Cuentan con toda la infraestructura necesaria para cubrir cualquier requerimiento solicitado. 

Equipo de trabajo:

Fomentan la comunicación e integración de todos los miembros de la organización. 

Pro actividad:

Detectan cualquier problema a tiempo y lo convierten en una oportunidad de mejora continua. 

Libertad:

Otorgan autonomía a sus colaboradores pero con la responsabilidad requerida para lograr los resultados óptimos. 

Competencia:

Siempre están preparados para entender las necesidades de sus clientes y para diseñar y entregar soluciones, con un profundo sentido de negocios. 

Superación:

Invierten responsablemente los recursos para lograr desarrollo y crecimiento sólidos.

3.2.4. Información comercial

Los servicios que brinda ATEB servicios son los siguientes: 





Factura Electrónica o

Servicio de Timbrado (folios) como PAC

o

Por WEB SERVICE/Por Timbrador ATEB

o

Aplicación Gratuita

ATEB-EDI o

ATEB-EDI OUTSOURCING

o

PORTAL WEB

Otros o

Mantenimiento a Productos

o

Código de Barras

o

Soporte 18

Los productos que vende ATEB Servicios son: 



Factura Electrónica o

ATEB COFIDI(Licencia Multiempresa)

o

PAC COFIDI(Light)

o

PAC ARCHIVO

o

PAC WEB

ATEB-EDI o

IDN COMMUNICATOR – INTEGRATOR

o

ASN ADMINISTRATOR

o

ATEB JIT

3.2.5. Estructura de ATEB Servicios

Nivel1

Nivel 2 Gerencia de Administración y Recursos Humanos Gerencia de Calidad Gerencia de Implementación y Soporte Técnico

Direcciòn General

Gerencia de Ventas Oficial de Seguridad de la Información (ISO)

Nivel 3 Depto. Admón. Depto. R.H.

Depto. Implementación Factura Electrónica Depto. Soporte Técnico Factura Electrónica Depto. Implementación y Soporte Técnico EDI

COFIDI Windows

Gerencia de Desarrollo COFIDI WEB

Diagrama 1. Organigrama por Áreas de ATEB Servicios.

19

3.2.6. Funciones como programador JAVA dentro de la Gerencia de Desarrollo de ATEB Servicios.

Mi experiencia profesional se centra alrededor de la gerencia de Desarrollo de ATEB Servicios, ya que mi ejercicio en esta es como programador JAVA encargándome de las siguientes funciones: 

Modificar código referente al sistema COFIDI WEB.



Crear nuevos módulos para el área de recepción y emisión de comprobantes fiscales electrónicos expedidos por medio del sistema COFIDI WEB.



Implementar y adecuar códigos ya existentes a programas que requerían de estos.



Programar nuevas aplicaciones que apoyan al área de soporte de ATEB servicios.



De brindar a los analistas un tiempo estimado de entrega del proyecto así como algunas ideas que puedan facilitar el uso del sistema al usuario.

3.2.5.1. Flujo del Proyecto

La Gerencia de Desarrollo se distribuye básicamente en COFIDI WINDOWS y COFIDI WEB, en este último es donde me desempeño profesionalmente. En el área de COFIDI WEB, se realizan y modifican proyectos todos bajo la plataforma de JAVA. El modo en el cuál opera la Gerencia de Desarrollo es a través de tickets, en estos se especifican las tareas a realizar. El proceso por el cual se asignan los tickets al área de COFIDI WINDOWS o COFIDI WEB es el siguiente: La Gerencia de Ventas es la responsable

de hacer los contratos con las debidas

especificaciones y notificar de estos por medio de un

CRM a la Gerencia de

Implementación y Soporte Técnico, está determina que departamento será el encargado de atender tal requerimiento, si este consiste solo de una modificación la asignación recaerá en el Depto. Soporte Técnico Factura Electrónica, o viceversa es la creación, adecuación o implementación de uno de los productos de ATEB Servicios este tendrá efecto en el Depto. Implementación Factura Electrónica, en estos departamentos los consultores son los encargados de hacer un análisis y diseño del requerimiento así como estimación del tiempo de desarrollo, para posteriormente guardar el proyecto en el CRM y enviarlo a la Gerencia de Desarrollo, donde dependiendo la especificación que contenga este, se confiere al área de COFIDI WINDOWS O COFIDI WEB para llevar a cabo la programación.

20

Una vez que sea establecido que programador será el encargado de llevar a cabo la creación o modificación del proyecto sus tareas consisten en: Revisar el CRM, donde se encuentra el proyecto a realizar de forma más detallada. En caso de que sea una modificación al código, informarse respecto al comportamiento de este y cuál sería la mejor solución. En caso de que sea un requerimiento nuevo, se hace una reunión con el líder de proyecto para revisar si se tiene

códigos con antecedentes parecidos

respecto

a la tarea

asignada solo para adecuarlos a la nueva especificación, en caso de no contar con estos, se lleva a cabo una discusión con el líder de proyecto para establecer cuál es la mejor vía de acción. Una vez que se termina la etapa de desarrollo, el programador informa que ha finalizado su tarea por medio del CRM y regresa el ticket al Depto. Implementación Factura Electrónica o Depto. Soporte Técnico Factura Electrónica,

donde el consultor se

encargará de hacer las respectivas pruebas al sistema y si el sistema cumple con todas las especificaciones estipuladas en la etapa de análisis será implementado en el ambiente de producción del cliente, de no ser así se regresa el ticket a programador detallando las incidencias que el sistema presenta.

3.3. Conexiones de COFIDI WEB El área de desarrollo de ATEB es la encargada de crear y dar mantenimiento a los sistemas COFIDI WEB y COFIDI Windows. Aquí se mencionara lo que compete al sistema COFIDI WEB, que está basado en una plataforma JAVA y frameworks como Struts 1.3.8, Hibernate , base de datos SQL y un servidor Tomcat . Las características generales que debe de tener el servidor que aloja al sistema COFIDI WEB con una concurrencia alrededor de 1500 clientes, son las siguientes: 

Sistema operativo Windows Server 2008 R2



Memoria RAM 8GB.



2 procesadores superiores a los 2 GHz



250 GB de disco duro

En cuanto a la base de datos lo aconsejable es que esta, radique en otra computadora con las características anteriormente mencionadas y tenga instalado SQL Server 2008.

21

Para una empresa que tiene alrededor de 10 sucursales, la aplicación como la base de datos pueden residir en la misma computadora, pero es aconsejable que en distinta partición, las características aconsejables para un buen desempeño del sistema son las siguientes: 

Sistema operativo Windows Server 2008 R2



Memoria RAM 4GB.



2 procesadores superiores a los 2 GHz



50 GB de disco duro

Figura 1. Arquitectura del sistema COFIDI WEB.

El sistema COFIDI WEB depende del sistema COFIDI Windows en lo que respecta a la asignación de permisos para los distintos perfiles de usuario. En cuanto a la conexión con una base de datos el sistema web lo hace desde el archivo server .XML que se encuentra en tomcat-6\conf, en este se escriben los parámetros como el nombre de la base de datos, puerto, usuario, contraseña y controlador de la base de datos ejemplo:

Después estos pasan a una clase que se aloja como librería de Tomcat y que se encarga de realizar la conexión con la base de datos, véase figura 1. El usuario del servidor se guardaba en la base de datos en la tabla usuarios no en el archivo de tomcat-user.xml, es decir cuando se arranca el sistema no va y lee un archivo si no va directo a la base de datos a la tabla usuarios, una para dar permisos al servidor y otra para dar acceso al usuario. El sistema está administrado básicamente por 4 archivos que son cruciales para su funcionamiento estos son: Archivos

Descripción

Web.xml

Determina la forma en las URL se asignan a los servlets y las direcciones URL que necesitan autentificación, entre otra información.

Struts-config.xml

Es un vínculo entre la vista y los componentes del modelo en el cliente Web. Desempeña un papel importante en la construcción de los componentes del controlador y configuraciones especificas de la aplicación. (ZOHO Corp, 2012)

Tiles-defs.xml

Índica la ruta de los .jsp así como en que parte del .jsp se pondrá determinado código.

Hibernate.cfg.xml

Es un fichero de mapeo que le dice al motor de Hibernate qué deberá almacenar, seleccionar, actualizar o eliminar en la base de dato y cómo. Tabla 1. Archivos de Configuración del sistema COFIDI WEB

23

3.4. Desarrollados

Algunos de los desarrollos que he programado durante mi estadía en ATEB Servicios son los siguientes:   

Módulo XLSS Aplicación Resultado de Timbrado COFIDI DELPHI

Los cuales son explicados más a detalle a lo largo del presente informe.

3.4.1. Módulo XLSS

Es un módulo del sistema COFIDI WEB que genera reportes con extensión .XLS. La finalidad de este módulo es crear documentos que contengan la información de las facturas emitidas por el usuario, sin repetir los montos, ya que esto se puede presentar a causa de las partidas que estén contenidas en las facturas. A su vez este módulo apoya al área contable de la empresa Volkswagen en el cálculo de sus balances. El módulo XLSS genera información a partir de filtrar las facturas por empresa, tipo documento, fecha de emisión inicial y fecha de emisión final, estos datos son obtenidos mediante variables de sesión, que se producen a través del módulo ―filtro‖ de COFIDI WEB; este último consta de las siguientes pestañas: 

Empresa: Exhibe todas las empresas a las que el usuario en sesión tenga acceso.



Tipo Documento: Como su nombre lo índica, esta pestaña muestra los tipos de documentos por los que se puede llevar a cabo la facturación. o

Factura

o

Nota de Crédito

o

Nota de Cargo

o

Recibo de honorarios

o

Recibo de arrendamiento



Estatus: Presenta los distintos estados por los que puede pasar un documento.



Clientes: Es una sección donde se capturar la razón social de estos.



Fecha: Muestra dos calendarios que hacen referencia a un rango de la fecha de emisión de las facturas.



Orden: Hace alusión al orden en que será presentada la información (ascendente 24

o descendente). 

Guardar: Almacena en la base de datos las opciones seleccionadas en el filtro.

En el caso de las pestañas Empresa, Tipo Documento y Estatus sus elementos son expuestos como casillas de verificación (checkbox), para el apartado de fecha se utilizan calendarios de la librearía YUI2, un ejemplo de esto véase figura 2.

Figura 2. Módulo de Filtro.

La generación del reporte se lleva a cabo a partir de un hipervínculo que se encuentra en la interfaz principal y que hace referencia al servlet GetPage, el hipervínculo tomo como nombre XLS_CONTA véase figura 3.

Figura 3. Hipervínculo XLS_CONTA.

La generación del reporte se realiza de la siguiente manera. Una vez

invocado el servlet

GetPage, este llama al método XLSS de la clase

GPDocsFactura el cuál se encargará de hacer una consulta a la tabla factura, tomando como parámetros las variables de sesión anteriormente mencionadas, el arreglo resultante de esta operación será iterado y sus elementos formaran una tabla de HTML la cuál será almacenada en una variable tipo texto, para después ser retornada al servlet GetPage

y asignada a las cabeceras de respuesta de este, las cuáles indicarán al 25

navegador que muestre un cuadro de diálogo para la descarga del archivo generado por el módulo XLSS (el código de este módulo puede verse en el Anexo A). El cuadro de diálogo presenta las opciones de abrir o guardar archivo como se índica en la figura 4.

Figura 4. Resultado de hacer clic en el hipervínculo XLS_CONTA.

El resultado se puede visualizar en Excel o en cualquier otra hoja de cálculo, una vez abierto el archivo este presentara datos como folio Interno,

Fecha Fiscal,

Tipo

Documento, Moneda, Serie Fiscal, Folio fiscal, Cliente, Monto etc., véase figura 5.

Figura 5. Resultado de ejecución del módulo XLSS.

26

Para mayor comprensión acerca de la generación de este reporte, véase el siguiente diagrama de flujo.

Diagrama 2. Representación Grafica del Flujo de Módulo XLSS

3.4.2. Aplicación Resultado de Timbrado

Es un sistema JAVA Application que apoya a los consultores del área de implementación y soporte de ATEB Servicios, este tiene como objetivo facilitar el proceso de recuperación de resultado de timbrado, esto con la finalidad de que los consultores de ATEB Servicios puedan brindar de manera oportuna un estatus de los documentos que fueron enviados a timbrar. Dado que sean presentado problemas en la red que conecta a ATEB Servicios con el SAT, esto ha provocado que en algunas ocasiones el documento que fue enviado al SAT para ser sellado, regrese sin este, sin embargo esto no quiere decir que la factura no allá sido sellada por parte del SAT, lo que hace necesario una revisión minuciosa y sujeta a errores por parte de los consultores de ATEB, he de ahí la necesidad de automatizar este proceso.

27

Este sistema se encarga de enviar a un web service el documento .XML que fue expedido por medio de COFIDI WEB, para llevar a cabo un estudio en la base de datos del PAC tomando como parámetros de búsqueda ciertos nodos claves del archivo .XML como RFC, Razón Social, empresa, factura etc. De esta manera se verifica si existe un sello que corresponda a los nodos del archivo .XML que fue enviado, una vez que se detectada esta información, se procede a mostrar el resultado en un área de texto del sistema Resultado de timbrado y se le informa al cliente el estado en el que se encuentra su documento, si no se genero el sello se le pide al cliente que vuelva a enviar su documento por medio del sistema COFIDI WEB, caso contrario si se origino el sello entonces un consultor de ATEB Servicios toma este registro de la base datos y lo pega al documento .XML en el nodo sello, para una visión más clara de este flujo véase el siguiente diagrama.

Diagrama 3. Representación grafica del Flujo de la Aplicación Resultado de Timbrado.

Dada la simplicidad del programa Resultado de Timbrado, este se desarrollo como una aplicación awt que consume un web service y muestra una interfaz donde se puede seleccionar un archivo .XML y así exhibir en un área de texto el resultado que arroje el web service, ejemplo de interfaz véase figura 6.

28

Figura 6. Aplicación Resultado de Timbrado.

3.4.3. COFIDI DELPHI

Es un sistema realizado en base a los requerimientos de la empresa Delphi, que toma como plataforma al sistema COFIDI WEB, las adecuaciones que se hicieron a este sistema recaen en el área de recepción de facturas, esto con el objetivo de tener mayor control respecto a la ejecución de diversas funciones. El sistema COFIDI DELPHI consta de dos módulos padres que son

Emisión

de

Comprobantes Fiscales (Documentos Clientes) y Recepción de Comprobantes Fiscales (Documentos Proveedores), una de sus principales funciones de estos módulos es mostrar una lista de los comprobantes fiscales con sus respectivos datos como: ID del documento, Empresa, Tipo, Serie, Folio Fiscal, Fecha Emisión, Proveedor, RFC, Razón Social, Monto, Fecha recepción, Estatus, Adenda etc. El módulo de Recepción de Comprobantes Fiscales de COFIDI DELPHI fue modificado ya que la empresa Delphi precisaba la implementación de funciones automatizadas para esta área,

por lo cual se desarrollaron los siguientes módulos: Archivos Adjuntos,

Eventos CFD, Vista Previa, INVOICE PROCESSED, PROBLEM INVOICE, Agregar Soporte, Cancelar documentos, Rejected, Exportar

.XML, APPROVER -OK y

APPROVER –REJECTED.

29

El acceso a estos módulos es delimitado por el perfil de usuario y por el estatus en el que se encuentra el comprobante seleccionado, lo que provoca diversos tipos de conjuntos (Ver Tabla en Anexo C). A partir de estos conjuntos se construyen múltiples menús contextuales que serán accedidos por medio de hacer clic derecho sobre un registro de la lista Documentos Proveedores que es presentada por el módulo Recepción de Comprobantes Fiscales, ejemplo véase figura 7.

Figura 7. Menú para cambio de estatus del sistema Delphi

3.4.3.1. Elementos del Menú Contextual

Los elementos del menú que se me solicito desarrollar fueron los siguientes:



PROBLEM INVOICE



Archivos Adjuntos



Eventos CFD

A continuación una breve explicación acerca de su funcionamiento.

3.4.3.1.1. Elemento PROBLEM INVOICE

Este elemento se encarga de mostrar los diversos problemas que puede presentar un comprobante fiscal como: 30



Requisitos fiscales/Año fiscal no correspondiente.



Firmas de autorización/sello de materiales.



No.O.C./Incorrecto/monto/vigencia/completa/partida no incluida/para DSSI/termino de pago.



Docto con información ilegible/copia de factura/falta hojas o soporte/error de digitalización.



Informe de recibo faltante/incorrecto/devolución de material o no recibido.



Tipo de moneda diferente/diferencia en precio.



Sobre embarques/material o servicio pagado/servicio incompleto o no recibido.



VNA pendiente de compras/inactivo/inexistente.



Cuenta contable inexistente/incorrecta.



Presupuesto excedido Work orders.



Otros.

Estos problemas son expuestos a través de una lista desplegable y una vez catalogado el problema se habilita un combobox que contiene los nombres de los destinatarios a quien se le enviará un email para que este apruebe o rechace la factura. Si el destinatario no aparece en la lista, se le da la opción al usuario de capturar el correo electrónico del destinatario. Otras de las funciones que realiza este elemento es la modificación del estatus del comprobante, así como la carga de datos a la tabla CfdeventosLog que funge como bitácora donde se índica que usuario llevó a cabo la modificación del estatus así como la fecha y hora en que sucedieron estos cambios. El funcionamiento del elemento PROBLEM INVOICE se inicia a partir

de hacer clic

derecho sobre un comprobante fiscal contenido en la lista de Documentos Proveedores y muestra una interfaz que contiene una lista desplegable, en la cual se exponen los diversos problemas que pudo presentar el comprobante fiscal, en caso de que se seleccione un problema distinto de ―Requisitos fiscales/Año fiscal no correspondiente‖, se activara un combobox que contendrá los nombres de los usuarios del perfil aprobador, véase figura 8.

31

Figura 8. Cuadro de diálogo PROBLEM INVOICE

En caso de que se haya activado la lista de aprobadores pero que el aprobador solicitado no se encuentre en ella, se muestran áreas de texto para

el ingreso de un correo

electrónico y una nota, esto con la finalidad de enviar un email con el problema que presento la factura, para su posterior aprobación o rechazo, véase figura 9.

Figura 9. El aprobador no está en la lista.

Una vez que se ha seleccionado un tipo de problema y/o un aprobador en caso de existir este último en la lista de aprobadores o bien de ingresar los datos de este y que se haya hecho clic en el botón Guardar, se enviarán los datos al servlet HandledStatus el cuál creará una instancia de la clase CFDProblemFacDto, para que el objeto resultante de esta llame al método manda () que se encarga de filtrar la información por tipo de problema. Dependiendo del tipo de problema seleccionado la función manda () enviará la información a los métodos cancelada () o aprobal (). Para mayor información acerca de la función manda (), consultar Anexo C. 3.4.3.1.1.1. Función cancelada( )

En el tema anterior se habló acerca de la función manda (), la cual filtra los números de problema a sus respectivas funciones, para el caso de la función cancelada (), basta con que el usuario haya seleccionado el problema “Requisitos fiscales/Año fiscal no 32

correspondiente” y haga clic en botón Guardar. A continuación una breve explicación de lo que hace el método cancelada ():



Actualiza el documento a estatus Cancelada.



Llena un log donde se describe a que estatus fue actualizado, quien lo modificó y la hora. Ejemplo de código:

LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: Cancelled", request, true,"13");

Esto se ve reflejado en la opción del menú Eventos CFD (véase figura 10).

Una vez que hacen clic en esta opción, les aparecerá un cuadro de diálogo como el que se muestra en la figura 11.



Busca en la tabla contactos el email del proveedor para después mandar un correo electrónico a este, con una URL que los re direcciona al módulo autorización del sistema COFIDI DELPHI en donde el aprobador tendrá que autentificarse para que el sistema le permitirá el acceso al módulo RedocProv, donde podrá ver el problema de la factura y entonces decida 33

si aprobarla o rechazarla. En la figura 12 se muestra un ejemplo de la URL que le llega al aprobador vía email.

Figura 12. Liga enviada por email para aprobadores

Debido a que los aprobadores de comprobantes fiscales no tienen en su totalidad acceso al sistema COFIDI DELPHI porque sólo pueden aprobar o rechazar facturas, se programo el módulo RedocProv que únicamente es dependiente del sistema COFIDI DELPHI en cuanto al módulo autorización, ejemplo véase figura 13.

Figura 13. Acceso a Aprobadores que son del grupo RP

Para tal caso se crearon grupos especiales que si empiezan con RP indican al módulo de autorización de COFIDI DELPHI que son aprobadores de facturas y que por consecuencia los re direccione al Action RevdocProv. RevdocProv se encargará de hacer una consulta a la tabla CFDProveedor por ID de proveedor el cuál fue obtenido de la URL (como se puede observar el la figura 13) que les llegó por correo electrónico, los datos obtenidos de este proceso llenan un FormBean, para que a partir de los atributos contenidos en este, el .jsp pueda presentar la información de la factura como se muestra en la figura 14. 34

Figura 14. Vista para Aprobadores

Como se puede observar en la figura 14, se describe toda la información referente al documento que fue cancelado, como el número de proveedor, serie, folio fiscal, RFC, Razón Social, así mismo, muestra una bitácora que describe los estatus por los que ha pasado el documento, quien la ha cambiado de estatus y la fecha de estos cambios. También cuenta con un módulo donde el aprobador puede cambiar el estatus del documento ya sea á aprover ok o aprover rejected (para mayor información acerca de la función cancelada( ); consultar Anexo C). 3.4.3.1.1.2. Función Aprobal( )

Esta función es invocada siempre y cuando el problema que haya seleccionado el usuario sea diferente de ―Requisitos fiscales/Año fiscal no correspondiente‖, las acciones que realiza esta función son: 

Actualiza el estatus a Problem Invoice o Aprobal queue dependiendo los problemas seleccionados.



Llena un log que hace las tareas de bitácora, como el descrito en la anterior función cancelada ( ).



Envía un email a los aprobadores que fueron seleccionados a partir de la lista desplegable o a los correos electrónicos que fueron ingresados mediante cajas de texto, esto con la finalidad de que los usuarios accedan al sistema y verifiquen cuál fue el problema que presentó su factura y se decida si aprobarla o rechazarla, así como que cambios sufrió esta. 35

A continuación se muestra el diagrama de flujo del proceso PROBLEM INVOICE.

Diagrama 4. Representación grafica del flujo del Área de Recepción de Facturas COFIDI DELPHI.

36

3.4.1.2. Elemento Archivos Adjuntos

Otro elemento del menú es Archivos Adjuntos (véase figura 15).

El cuál muestra y descarga los archivos que están relacionados por ID de proveedor con el documento seleccionado de la lista que es proporcionada por el módulo de recepción de facturas de COFIDI DELPHI, ejemplo ver figura 16.

Este elemento es accedido por medio de hacer clic derecho sobre un registro de la lista presentada por Documentos Proveedores, una vez que sea ejecutado el menú contextual y se ha hecho clic derecho sobre el elemento ―Archivos Adjuntos‖, este ejecutara una serie de acciones las cuáles mostraran un cuadro de diálogo, (véase figura 16) que contendrá los links que hacen referencia a los archivos a descargar, basta sólo con hacer clic sobre estos para que se inicie el proceso de descarga, ver figura 17.

Figura 17. Archivo adjunto descargado.

37

Para mayor informa acerca del Módulo Archivos Adjuntos véase Anexo C. 3.4.3.2. Reportes DELPHI

Este módulo secunda a la empresa Delphi en el área de recepción de comprobantes fiscales, ya que este módulo se ocupa de la generación de diversos reportes como:



Historial de Documentos



Documentos en queue de Aprobador



Días transcurridos - primer acceso



Documentos Digitalizados por Localidad y Logon ID



Notas de Crédito y Notas de Cargo



Master de Proveedores



Violaciones de Acceso



Ageing on Resolution



Document Processed Trend



Purchase Order Cycle Time



Blocked Billing Resolution



Work State Wise



Purchase Order Review Auditor



Cargos a Proveedores por uso del Portal



Facturas Internas



Auditoria de Usuario

Estos reportes le permiten a la empresa Delphi tener una visión más clara acerca de lo que acontece en esta área y así mismo llevar a cabo una mejor toma de decisiones referente a esta. Este módulo toma como base al filtro de búsqueda del sistema COFIDI DELPHI, el cual se divide básicamente en las siguientes pestañas: Empresas, Tipo Documento, Fecha Emisión y Estatus, esto le permite reutilizar los parámetros que se generan a partir de las pestañas anteriores. A su vez este módulo añade al filtro de búsqueda la pestaña ―Reportes‖, la cual contiene una lista desplegable con los nombres de los reportes 38

anteriormente mencionados, una vez que el usuario selecciona un reporte, dependiendo del que haya sido elegido, se ocultan o muestran las demás pestañas del filtro de búsqueda esto con la intención de que el usuario solo pueda seleccionar los parámetros necesarios para generar el reporte que fue electo, ejemplo véase figura 18. La visualización de estos reportes puede llevarse a cabo en Excel o en cualquier otra hoja de cálculo. Cabe mencionar que los reportes son generados por una aplicación hecha en .NET, pero a partir de la información emitida por el filtro de búsqueda de COFIDI DELPHI.

Figura 18. Módulo de generación de parámetros para Reportes Delphi

Dado que del filtro de búsqueda se obtendrán los parámetros necesarios para la generación del reporte, estos son guardados en la tabla Cfdreportes, en la cual existen campos que son claves como: generado, tipo de reporte y el id. El campo generado sirve como bandera, ya que este inicia con el valor ―0‖ que índica que solo se ha guardado la información en la tabla, pero que el reporte no ha sido creado. Para que se pueda realizar el reporte se creó un proceso externo en .NET que lee cada cierto tiempo esta tabla e inspecciona el campo generado, si este contiene un ―0‖, toma los campos pertenecientes a este registro y construye el reporte a partir de estos, después el campo generado lo actualiza a ―1‖, esto índica que el reporte sea producido. Para que el usuario pueda visualizar los reportes que ya han sido generados por la aplicación de .NET, se creó el hipervínculo ―Reportes‖ en el menú principal de COFIDI DELPHI, cuando se ha hecho clic sobre este link, este invoca aun Action encargado de buscar en la tabla Cfdreportes aquellos registros que en su campo generado contengan ―1‖ para después mostrar la descripción de estos como enlaces, ejemplo ver figura 19.

39

Figura 19. Módulo que muestra los reportes que ya han sido generados.

Una vez que han hecho clic sobre alguno de los hipervínculos que han sido desplegados, estos invocan a un DownloadACTION que se encarga de revisar la tabla CfdfileReport donde el proceso de .NET guardó el archivo generado, para después extraer el archivo y pasarlo por cabeceras de respuesta y así indicar al navegador que se trata de un archivo que va hacer descargado. Esta es una manera sencilla de generar diversos tipos de reportes conforme a los filtros de búsqueda establecidos en COFIDI DELPHI y a su vez un ejemplo de reutilización de código.

40

4. Discusión y Análisis En mi estancia durante ATEB Servicios puedo comentar mi experiencia adquirida en el área de desarrollo de sistemas, en el manejo de JAVA y frameworks como Struts, Hibernate y librerías como YUI2. Lo cual me ha enriquecido respecto al funcionamiento y creación de sistemas, ya que al enfrentarse a los problemas que puede presentar un sistema, es cuando dimensionas cuáles son las verdaderas deficiencias causadas por no llevar una metodología, o bien el hecho de tratar de comprender un código ajeno te permite ver que si se lleva a cabo una apropiada documentación las tareas se simplifican en gran medida. Por lo que mi aportación fue en parte el comentar mi código. Esta experiencia me ha permitido tener una visualización más clara de cómo debe ser la interacción entre el usuario y el sistema, esto engloba el hacer páginas más dinámicas y amigables para el usuario. De manera indirecta el desarrollar sistemas incrementa tu conocimiento en otras zonas, tal es el caso de mi conocimiento adquirido respecto a la facturación electrónica. Dado que no se sigue una metodología que tenga bases en la Ingería de Software se han presentado diversos problemas tales como: 

No existe una adecuada división en los procedimientos que ejecuta el sistema lo cual provoca clases con miles de líneas de código lo que incita a

que su

entendimiento sea engorroso. 

Gran cantidad de los datos que se muestran en pantalla no estén guardados en variables de sesión lo que provoca pérdidas de información emitida por el usuario, a su vez esto último genera la recaptura de la información. Datos que fungen como índices de tablas son enviados por URL lo puede motivar un ataque más fácilmente.



Clases y variables con mnemónicos que no fomentan el entendimiento del sistema.



No se hace una estimación de los tiempos correcta, lo que provoca retrasos.



No se tiene en su totalidad analizados todos los requerimientos del cliente así como qué implica el llevar a cabo estos.



Base de datos que no sigue todas las reglas que estipula el modelo entidad relación, una de estas es que no están conectadas las tablas por llaves foráneas, esto a la larga repercute en que la base de datos contenga sedimento y si no se tiene una adecuada documentación respecto a esta será imposible su entendimiento. 41

5. Recomendaciones De acuerdo con el análisis anterior, a continuación proporciono algunas recomendaciones: Para hacer una adecuada estimación del software es necesario emplear una metodología o una combinación de varios modelos y practicas utilizados en la Ingeniería de Software, para formar un sistema de calidad total. Por ejemplo para una estimación más certera en cuanto a tiempo, esfuerzo y costo podría recomendar el modelo COCOMO o bien el método BISAD cuando los factores son subjetivos. Un modelo eficiente y probado es MoProSoft, ya que se ajusta al tamaño de las empresas mexicanas y emplea patrones para definir cada proceso concerniente con la calidad en el desarrollo y mantenimiento de software. En cuanto al desarrollo de un programa web, considero que las variables de sesión simplifican el uso que el usuario da al sistema así como al programador le ofrece un acceso más eficiente a los datos desde cualquier parte del sistema. Un modelo entidad relación bien implementado es de gran ayuda en la administración de una base de datos. Lo que recomendaría a la Licenciatura en Informática respecto a las materias de programación, es que vieran lenguajes de programación más comerciales así como el uso de sus frameworks. Un tema muy importante y actual es lo referente a los web service, por lo tanto se debe ver este tema en clases ya que dado el gran flujo de información que circula por una red, la variedad de plataformas que se manejan hoy en día y las distancias entre los lugares geográficos, hace de crucial importancia el hacer sistemas que se puedan integrar con otros no importando las anteriores barreras. Como informáticos que se dedican a la programación no deberían de estar tan relacionados con el diseño de interfaces, sin embargo esta va de la mano con el hecho de crear un sistema amigable por lo que si se tiene un conocimiento más amplio en cuanto al diseño grafico y lo que conlleva este, ambas partes darían como resultado un sistema más optimo.

42

6. Conclusión Como primera instancia puedo decir que cuando ya estás en el ejercicio laboral te enfrentas a muchas situaciones como el hecho de tener que entender otros temas tal es el caso de la facturación electrónica o bien el comprender las ideas de otras personas ya que esto se vuelve una práctica muy común en el área de programación, así como siempre estar al día ya que la necesidad de sacar adelante un proyecto te lleva a buscar y aprender constantemente. Otro factor importante es el ser audaz ante los problemas que se te presentan así como creativo y perseverante al final del día esto te enriquece y es lo que va formando al profesional. La carrera en informática es la encargada de darnos las bases de diversas ramas que la conforman pero

depende de nosotros el sumergirnos en un área en especifico y

dominarla. He pensado que el área de programación no es tan difícil, lo que la hace complicada es el carecer de conocimiento y experiencia, a su vez la falta de estos es por indisciplina, para lograr algo nuestro principal enemigo es uno mismo. El hecho de que funcione un programa no implica que este sea de calidad, para lograr esto es necesario hacer uso de las buenas prácticas, ya que obedeciendo a un estándar es más fácil predecir su comportamiento. La rama de programación no nada más compete a la experiencia y conocimiento de un lenguaje de programación, sino también a la mente creativa, al hecho de recurrir a la teoría de conjuntos, a las matemáticas para simplificar procesos. Considero que la informática

desarrolla la creatividad, no solo en el área de

programación si no en todas sus áreas convirtiéndola en una forma de expresión y esta a su vez en una especie de arte. Sin embargo la creatividad debe de ser encaminada para lograr el objetivo que se estableció en el análisis y diseño de sistemas. El programar es una tipo de juego mental, que se vuelve vicio por aquel sentimiento que se genera una vez logrado el sistema. Existe un mito respecto a que ciertos lenguajes son mejores por el hecho de que sean libres o no. Yo creo que todo se reduce a la mente humana, un ejemplo de esto es la eterna discusión entre PHP y JAVA, donde considero que la clave radica en el programador.

43

Bibliografía Nagappan, R. (2003). Web Services. En R. Nagappan, Developing JAVATM Web Services (pág. 22). India: WILEY. Scott, S. (2002). En S. Scott, Short Scott.2002 Creación de Servicios Web .XML para la plataforma Microsoft ®.NET (págs. 22-26). España: McGraw-Hill. Sierra, M. A. (2008). STRUTS. En M. A. Sierra, STRUTS (págs. 16-32). España: Alfaomega. Facturador Electrónico. (21 de Abril de 2010). Facturador Electrónico. Recuperado el 05 de Abril de 2012, de Facturador Electrónico: http://www.facturadorelectronico.com/Glosario.aspx Forma Select. (17 de Julio de 2008). Forma Select. Recuperado el 01 de Mayo de 2012, de Forma Select: http://www.formaselect.com/curso/experto-en-sql-server-2000/Introduccion-a-SQLServer%202000.pdf Gidon, B. (01 de Enero de 2012). W3c. Recuperado el 01 de Mayo de 2012, de http://www.w3c.es/Divulgacion/GuiasBreves/Tecnologias.XML Oracle Corporation. (11 de Febrero de 2009). java. Recuperado el 18 de Abril de 2012, de java: http://www.java.com/es/download/faq/whatis_java..XML SERVICIO DE ADMINISTRACIÓN TRIBUTARIA. (10 de Noviembre de 2011). SAT. Recuperado el 05 de Abril de 2012, de SAT: http://www.sat.gob.mx/sitio_internet/asistencia_contribuyente/principiantes/comprobantes_fisc ales/66_20171.html SERVICIO DE ADMINISTRACIÓN TRIBUTARIA. (30 de Junio de 2011). SAT. Recuperado el 05 de Abril de 2012, de SAT: http://www.sat.gob.mx/sitio_internet/e_sat/comprobantes_fiscales/15_6563.html SERVICIO DE ADMINISTRACIÓN TRIBUTARIA. (15 de Febrero de 2011). SAT. Recuperado el 06 de Abril de 2012, de SAT: http://www.sat.gob.mx/sitio_internet/asistencia_contribuyente/principiantes/comprobantes_fisc ales/66_18779.html Unife. (06 de Enero de 2012). Unife. Recuperado el 20 de Abril de 2012, de Unife: www.unife.edu.pe/ing/desarrollo.doc ZOHO Corp. (01 de Enero de 2012). ZOHO Corp. Recuperado el 11 de Mayo de 2012, de ZOHO Corp: http://www.webnms.com/webnms/help/developer_guide/web_client/web_struts_config.html

44

ANEXO A. Módulo XLSS La generación del Reporte XLSS es llevada a cabo accionando el siguiente hipervínculo: XLS _Conta   Este link toma una ruta definida, a través de pageContext.request.contextPath

y le

agrega la abreviación gp (servlet GetPage), esta índica que servlet debe ser invocado así como los parámetros que deben ser enviados para la realización del reporte. Una vez que llega al servlet GetPage los parámetros tb y

fmt, estos son leídos y

dependiendo de su contenido se ejecutan ciertos procesos ejemplo: if ("xlss".equals(fmt)) { // comparaciòn de parametros gpList = new GPDocsFactura(request); String xls = ((GPDocsFactura) gpList).Xls(alEmpresas);/*regresa un cadena que contiene un HTML que será enviado a través de las cabeceras de respuesta a Excel para pintar la información emitida de la consulta hecha a la bd*/ response.reset(); response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "inline; filename=\"report.xls\""); out.println(xls); out.close(); return; }

El código anterior muestra una validación donde

el parámetro fmt si es igual xlss,

procederá hacer el código para generar el archivo .xls. Una vez leídos los parámetros se manda a

llamar al método XLS de la clase

GPDocsFactura el cual hace una consulta de forma nativa (SQL) a la base de datos y los registros obtenidos de esta consulta son almacenados en un objeto StringBuffer que tiene como objetivo concatenar cadenas de texto en tiempo de ejecución ejemplo. /*Pregunta que genera .xls dependiendo de los filtros de empresa, tipo de documento, fecha de emisión inicial y final*/ String pregunta = "select fac.Factura as FolioInterno," + " convert(nvarchar,fac.FechaEmision,120) as FechaFiscal, " + "fac.TipoDocumento as TipoDocumento, " + "fac.Moneda as Moneda, " + "fac.Serie as SerieFiscal, " + "fac.FolioFiscal as Foliofiscal, " + "fac.Cliente as Cliente, " + "fac.Monto as Monto, " + "fac.Impuesto as Impuesto, " 45

+ "fac.Customfield12 as TerminosCobro, " + "fac.Customfield10 as referencia, " + "fac.Usuario as usuario, " + "conp.Descripcion as Condiciones, " + "facdt.Descripcion as descripcion, " + "facdt.DescripcionFactura as descripcionfactura, " + "facdt.Customfield08 as cuenta, " + "facdt.Customfield10 as centrocostos, " + "facdt.cantidad * facdt.precio as importelinea, " + "facdt.impuestoporcentaje as CodigoImpuesto, " + "fac.TipoCambio as TipoCambio from " + catalog + "." + schema + ".Factura fac, " + catalog + "." + schema + ".CondicionesDePago conp, " + catalog + "." + schema + ".facturadtl facdt " + "where CONVERT(varchar, conp.Consecutivo)=fac.CustomField11 " + "and fac.Empresa=facdt.Empresa and fac.id=facdt.Id and " + "fac.factura=facdt.factura and fac.Empresa in (:emp) and " + "fac.TipoDocumento in (:ty) and fac.FechaEmision between :fi and :ff"; //Se pasa el string anterior a un createSQLQuery para que se ejecute la búsqueda Iterator ok = session.createSQLQuery(pregunta) .addScalar("FolioInterno", Hibernate.STRING)//0 .addScalar("FechaFiscal", Hibernate.STRING)//1 .addScalar("TipoDocumento", Hibernate.STRING)//2 .addScalar("Moneda", Hibernate.STRING)//3 .addScalar("SerieFiscal", Hibernate.STRING)//4 .addScalar("Foliofiscal", Hibernate.STRING)//5 .addScalar("Cliente", Hibernate.STRING)//6 .addScalar("Monto", Hibernate.DOUBLE)//7 .addScalar("Impuesto", Hibernate.DOUBLE)//8 .addScalar("TerminosCobro", Hibernate.STRING)//9 .addScalar("referencia", Hibernate.STRING)//10 .addScalar("usuario", Hibernate.STRING)//11 .addScalar("Condiciones", Hibernate.STRING)//12 .addScalar("descripcion", Hibernate.STRING)//13 .addScalar("descripcionfactura", Hibernate.STRING)//14 .addScalar("cuenta", Hibernate.STRING)//15 .addScalar("centrocostos", Hibernate.STRING)//16 .addScalar("importelinea", Hibernate.DOUBLE)//17 .addScalar("TipoCambio", Hibernate.DOUBLE)//18 .setParameterList("emp",alEmpresas)/*se le pasa el arreglo alEmpresas para que busque de acuerdo a las contenidas en este*/ .setParameterList("ty",alTiposDocs)/*se le pasa el arreglo alTiposDocs para que busque de acuerdo a los documentos contenidos en este*/ .setParameter("fi", dtIni)//fecha de emisión inicial .setParameter("ff", okf)//fecha de emisión final 46

.list() .iterator();

Después se forma las columnas que contienen los títulos que van a aparecer en el archivo de .xls, como se muestra en el siguiente código:

//Aquí se empieza a pintar el HTML que se va a pasar a Excel sb.append(""); String makeCols = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; sb.append(makeCols);/*todo esto fue lo que se va a pintar incluso estos nombres son los encabezados del Excel*/

A partir de que se itera esta consulta es cuando se empieza a formar el HTML, ejemplo de iteración véase figura 20.

47

Figura 20. Código de Iteración que va formando una tabla de HTML

Después de que el servlet gp recibe la cadena formada, este escribe la cadena en un archivo y se le índica al navegador mediante las cabeceras de respuesta que es un archivo de Excel.

ANEXO B. Aplicación Resultado de Timbrado A continuación se muestra el proceso de construcción de la aplicación Resultado de Timbrado así como su modo de ejecución. Dado que esta aplicación consume al web service de timbrado, se tuvo que hacer una importación de este último para poder consumirlo ejemplo: wsimport https://cfdi.timbrado.com.mx/cfdi/wstimbradorec.asmx?wsdl -p expe –keep Donde wsimport es el comando que analiza los documentos .WSDL que describe el servicio Web y crea un conjunto de clases auxiliares. Una vez que ya se tiene los .java generados a partir del comando anterior, se procedió a crear la interfaz awt ejemplo. public Interfaz() { miCampoTexto.setBounds(20, 65, 350, 25);/*tamaño de la caja de texto donde se insertara la ruta del archivo elegido*/ JButton abrir = new JButton("Buscar Archivo"); abrir.setBounds(10, 35, 150, 25);/*botón que activa ventana para elegir archivos*/ Filtro filtro = new Filtro();/*clase que se encarga de filtrar segun el tipo de archivos*/ file1.addChoosableFileFilter(filtro); 48

//dependiendo el archivo elegido se filtra abrir.addActionListener(new ActionListener() { //validaciones en caso de que no se seleccione un archivo public void actionPerformed(ActionEvent e) { int a = file1.showOpenDialog(null); if (a == 0) { String path = file1.getSelectedFile().toString(); ruta = path; miCampoTexto.setText(ruta); System.out.println(path + a); } else { ruta = "No selecciono archivo."; } miCampoTexto.setText(ruta); } }); Button miBoton = new Button("Enviar");/*Botón encargado de enviar el archivo seleccionado en el código anterior al web service */ miBoton.setBounds(390, 65, 150, 25); TextArea miAreaTexto = new TextArea(); miAreaTexto.setBounds(75, 100, 450, 270);/*dimensiones de la caja de texto donde aparecerá el resultado del envió al web service */ miBoton.addActionListener(new MiActionListener(miCampoTexto, miAreaTexto)); //todos los elementos son puestos en un frame Frame miFrame = new Frame("Resultado de Timbrado"); miFrame.setLayout(null); miFrame.add(abrir); miFrame.add(miCampoTexto); miFrame.add(miBoton); miFrame.add(miAreaTexto); miFrame.setSize(600, 400); miFrame.setResizable(false); miFrame.setVisible(true); miFrame.addWindowListener(new Conclusion()); } } Lo primero que vemos es, que se crean objetos file1 y miCampoTexto, el objeto file1 es un objeto que pertenece a la clase JFileChooser y en cuanto al objeto miCampoTexto este pertenece a la clase TextField, el primero sirve para mostrar la caja de dialogo que contiene las rutas de los archivos a seleccionar y el segundo objeto miCampoTexto es una caja de texto donde se escribirá la ruta que se seleccione a partir de hacer clic en el botón buscar Archivo. El objeto file1 hace una instancia a la clase Filtro que se encarga de filtrar los archivos solo por formato .XML, después se crea un objeto que se llama abrir que pertenece a la 49

clase JButton, este es solo un botón que tiene un método que hace una instancia a la clase ACTIONListener , está a su vez tiene un método por default que se llama ACTIONPerformed(ACTIONEvent e) el cuál se activara una vez que se haga clic en el botón que lleva por título Buscar Archivo y se encargará de hacer una validación respecto a si se eligió o no un archivo. En caso de que si se haya seleccionado un archivo la ruta que se eligió se escribe en el TextField miCampoTexto. Una vez que ya se tiene la ruta se hace clic en el botón que lleva por título Enviar, este al igual que el botón Buscar Archivo tiene un método addACTIONListener() que hace una instancia a MiACTIONListener y llena su función constructora pasando como parámetros la ruta del archivo y un objeto que se llama miAreaTexto que pertenece a la clase TextArea, este último es donde se publicara el resultado de esta tarea. La clase MiACTIONListener tiene por default el método public void ACTIONPerformed( ACTIONEvent evt ) que es el que se ejecutara una vez que esta sea llamada, (cabe mencionar que este método se llama por default porque es una clase que extienden de una clase oyente como ACTIONListener). Esta función se encarga primero de recoger el String que escribe el usuario en la caja de texto TextField miCampoTexto y almacenarlo en una variable de tipo String que toma el nombre de ruta, después se crea una variable de tipo arreglo de bytes (byte[] buffer) que tiene por nombre buffer y aquí se le pasa primero el tamaño de la variable ruta. Después se hace una instancia a la clase FileInputStream, se le pasa la variable ruta y el arreglo buffer que debe de leer, enseguida se cierra el archivo ejemplo. ruta=oCampoTexto.getText();/*la ruta que se establece en la caja de texto oCampoTexto es asignada a la variable ruta para después ser leído el archivo especificado en la caja de text*/ byte[] buffer=null; try{ buffer = new byte[(int) new File(ruta).length()]; FileInputStream fis = new FileInputStream(ruta); fis.read(buffer); fis.close(); }catch(Exception ex){ ex.printStackTrace(); return; }

A continuación se genera el código que consumirá al web service, primero se hace una instancia a la clase ObjectFactory y se creará de esta un objeto que se llame of , esta clase contiene de manera resumida la llamada a las clases que integran el web service, después el objeto of

invoca al método createAuthenticationHeader() que a su vez 50

retornara una instancia a AuthenticationHeader(), esto servirá para llevar a cabo la autentificación de usuarios y que el web service brinde el acceso al sistema, ejemplo: //código para autentificarse en el web service ObjectFactory of = new ObjectFactory(); AuthenticationHeader ah = of.createAuthenticationHeader(); ah.setUserName("0000000001"); ah.setPassword("qpzmal");

Una vez autentificados los usuarios en el sistema se procede

a pasar la instancia

generada a través de of.createAuthenticationHeader() a un JAXBElement, esta clase representa la información acerca del .XML donde está declarada dicha clase es decir en el .WSDL, después de hace una instancia ServicioRecTimbrePruebas creando un objeto stp este servirá para invocar a la clase ServicioRecTimbrePruebasSoap

y hacer un

objeto de esta ejemplo: /*Hace llamado a la clase soap que contiene el protocolo de comunicación para enviar y recibir */ JAXBElement jah = of.createAuthenticationHeader(ah); ServicioRecTimbre stp = new ServicioRecTimbre(); ServicioRecTimbreSoap stpSoap = stp.getServicioRecTimbreSoap();

Esto con el fin de tener acceso a los métodos expresados en el web service, ejemplo de clase ServicioRecTimbrePruebasSoap:

/ *@parametros .XMLBytes @return returns java.lang.String*/ @WebMethod(operationName = "GeneraTimbreRec", action = "https://cfdi.timbrado.com.mx/cfdi/GeneraTimbreRec") @WebResult(name = "GeneraTimbreRecResult", targetNamespace = "https://cfdi.timbrado.com.mx/cfdi/") @RequestWrapper(localName = "GeneraTimbreRec", targetNamespace = "https://cfdi.timbrado.com.mx/cfdi/", className = "expe.GeneraTimbreRec") @ResponseWrapper(localName = "GeneraTimbreRecResponse", targetNamespace = "https://cfdi.timbrado.com.mx/cfdi/", className = "expe.GeneraTimbreRecResponse") public String generaTimbreRec( @WebParam(name = ".XMLBytes", targetNamespace = "https://cfdi.timbrado.com.mx/cfdi/") byte[] .XMLBytes);

Como es un web service que va a recibir un arreglo de bytes y la autentificación de usuario y que regresa una respuesta, se crean cabeceras ejemplo: 51

WSBindingProvider bp = (WSBindingProvider)stpSoap; Header hdr =Headers.create((JAXBRIContext)JAXBContext.newInstance(AuthenticationHeader.class ),jah); bp.setOutboundHeaders(hdr);

Una vez efectuado el código anterior la clase ServicioRecTimbrePruebasSoap invoca al método generaTimbreRec(buffer), donde se le enviará en forma de arreglo de bytes el archivo .XML a probar, para que el web service genere una respuesta y esta sea mostrada en el objeto textarea.

52

ANEXO C. Elementos del Menú Contextual COFIDI DELPHI

53

A continuación se explicará el desarrollo de los elementos para COFIDI DELPHI en cuanto al área de Recepción de Comprobantes Fiscales. Como primera etapa se crean los menús a partir de arreglos tipo JSON, tomando en cuenta los perfiles de usuario, ejemplo de menú para usuario tipo Administrador: var dmcdAnalistAdmon = [ {text: mis_lang.vistaPrevia, onclick:{fn: vistaPrevia}}, {text: mis_lang.archivosAdj, onclick:{fn: archivosAdjuntos}}, {text: "INVOICE PROCESSED", onclick:{fn: invoiceProcessed}}, {text: "PROBLEM INVOICE", onclick:{fn: problemInvoice}}, {text: mis_lang.agregarSoporte, onclick:{fn: agregarSoporte}}, {text: mis_lang.cancelar, onclick:{fn: cancelar}}, Figura 21. Menú Contextual Delphi {text: "REJECTED", onclick:{fn: rejected}}, {text: mis_lang.documentLog, onclick:{fn: eventosCFD}} ];

Elemento Problem invoice

Como se puede observar en el menú anterior, este se compone por diversas funciones que se activan con solo con hacer clic en una determinada opción, a continuación se explicará el elemento PROBLEM INVOICE, que llama a la función problemInvoice (), ejemplo de función.

function problemInvoice(){ var fstat = oRecord.getData("cfdstatus");//estatus del documento var dlg_problem = document.forms["dlgproblem"];//nombre del form dlg_problem.ACTION = "/"+appRoot+"/hs";//ruta del servlet dlg_problem["dpd_dt_id"].value = oRecord.getData("id");//id del proveedor dlg_problem["dpd_prov"].value = oRecord.getData("proveedor"); dlg_problem["dpd_doc"].value = oRecord.getData("serie")+oRecord.getData("folioFiscal"); dlg_problem["ps"].value = oRecord.getData("cfdstatus"); YAHOO.docs_prov.container.dialog_problema.callback.argument = [myDataTable,oRecord]; YAHOO.docs_prov.container.dialog_problema.show(); dlg_problem["dpd_mot"].focus(); }

Esta función se encarga de mostrar diversos problemas a través de una etiqueta y también muestra dependiendo que problema se haya elegido una lista aprobadores al cuál se le enviará un email para que apruebe o cancele dicha factura. 54

El siguiente código es el encargado de pintar la interfaz sobre la que actúa la función problemInvoice ().

FolioInternoFechaFiscalTipoDocumentoMonedaTipoCambioSerieFiscalFoliofiscalClienteMontoImpuestoTerminosCobroReferenciaUsuarioCondicionesDescripcionDescripcionFacturaCuentaCentroCostosImporteLinea
55

:
:
:


En el código anterior, se puede observar a la etiqueta cuyo nombre es problemas, esta acciona a la función ver( ), gracias a su evento onchange( ), esta última se encarga de habilitar el aprobadores dependiendo de qué se haya seleccionado, ejemplo de función:

function ver(){ var problema=document.getElementById("proid").value;/*etiqueta select que contiene los problemas*/ document.getElementById("aproid").disabled=true;/*dependiendo del pr oblema elegido este será habilitado*/ if(problema==3 || problema==4 || problema==6 || problema==8 || problema==9 || problema==10 ||problema==11|| problema==12 ){ document.getElementById("aproid").disabled=false; }else{ document.getElementById("emailinfo").style.display="none"; } }

Si se activa el evento onchange( ) de la etiqueta aprobadores, este llama a la función esta( ), que se encarga de hacer validaciones respecto a que aprobador se eligió y dependiendo de esto se muestran o no los campos emailinfo y aproid ejemplo de función:

function esta(){ var divemail = document.getElementById("emailinfo");/*campo donde se escribirá el email del aprobador en caso de ser onetime es decir que no está registrado en la bd*/ var selectId = document.getElementById("aproid");//select que contiene los emails if( selectId.value == "0"){ divemail.style.display = "block"; }else{ divemail.style.display = "none"; } } 56

Y a su vez el código que hace posible la interfaz de Problem Invoice está dentro de un contenedor que es propio de YUI2, véase el siguiente código. YAHOO.namespace("docs_prov.container"); YAHOO.util.Dom.removeClass("dialog_problema", "yui-pe-content"); YAHOO.docs_prov.container.dialog_problema= new YAHOO.widget.Dialog("dialog_problema", { width : "50em", fixedcenter : true, visible : false, modal: true, constraintoviewport : true, buttons : [ {text:btn_lang.guardar,handler:handleSubmitDlgo}, {text:btn_lang.cancelar,handler:handleCancelDlgNR} ] });

Como se puede ver en el código anterior este consta de dos métodos uno handleSubmitDlgo y handleCancelDlgNR, el primero de ellos es el encargado de enviar al servlet, que opción del menú se selecciono y el estatus, para que este realice tareas como cambio de estatus, envió de email, llenado de un log que hace las tarea de bitácora, en cuanto al segundo botón este solo se encarga de cerrar la ventana de dialogo. A continuación se explicará las tareas que realiza el servlet en cuanto a la opción Problem Invoice. La primera tarea el servlet es hacer una instancia a una clase CFDProblemFacDto que se encargará de hacer la lógica del negocio, véase el siguiente código: else if (table.equals("profac")) { CFDProblemFacDto obj = new CFDProblemFacDto(request); obj.manda(); } El método manda( ) de la clase CFDProblemFacDto se encarga de filtrar la información para ejecutar la función de cancelación o la aprobación ejemplo: public boolean manda() { CFDProblemfacDAO actualiza = new CFDProblemfacDAO(request); String id = request.getParameter("dpd_dt_id");//id del proveedor String problema = request.getParameter("problemas");/*numero de 57

* problema elegido*/ boolean regre = false; String prevStat = request.getParameter("ps");//estatus del documento if (problema.equals("1")) {/*si el problema es 1 la factura * se tendra que cancelar*/ regre = actualiza.cancelada(id, prevStat); } else {/*el problema es distinto de 1 por lo tanto pasa aprobación*/ regre = actualiza.Aprobal(id, prevStat); } return regre; }

Función Cancelada( ) Si el problema que fue seleccionado es el numero ―1‖ que pertenece a la descripción del problema ―Requisitos fiscales/Año fiscal no correspondiente‖, como se puede observar en el código anterior se procede a invocar a la función cancelada( ) que se encarga de buscar en la tabla contactos el email del proveedor para después mandar un correo electrónico a este, con una liga que le permitirá el acceso al sistema para ver el problema de la factura y se decida si cancelarla o aprobarla. //query trae el email del proveedor de la tabla contactos String question = "select con.email from " + catalog + "." + schema + ".Contactos con, " + catalog + "." + schema + ".CFDProveedor pro " + "where con.Cliente=pro.Proveedor and pro.ID=:id"; String email = ""; /*el anterior query se ejecuta pasando como parámetro de búsqueda id*/ Iterator ques = session.createSQLQuery(question) .addScalar("email", Hibernate.STRING) .setParameter("id", Long.parseLong(id)) .list().iterator(); /*while que itera el resultado del query si este contine un dato se procedera a ser guardado en la variable email*/ while (ques.hasNext()) { email = ques.next().toString(); } /*la variable email diferente de vacio se llama a la función notificacfdaprobador encargada de enviar un email con el problema seleccionado al correo generado a partir del query anterior*/ if(!email.equals("")){

58

Funcs.notificaCfdAprobador (session,null, request, false, email, id, problema); }

La función Funcs.notificaCfdAprobador es la encargada de generar la liga y enviar al aprobador el email véase el siguiente código: public static void notificaCfdAprobador(Session session, Cfdproveedor cfdp, HttpServletRequest request, boolean esProduccion, String user, String id, String problema) { //funciòn encargada de enviar un email al proveedor COFIDIConfig cofidiInst = COFIDIConfig.getInstance(null); /*ruta del archivo properties que contine parametros para envio de email*/ String smtpPropsDir = cofidiInst.getPath() + "web\\"; String smtpPropsFile = smtpPropsDir + "smtp.cofidi.properties"; /*Busqueda del archivo properties si existe se hace una carga de los datos contenidos en este*/ File fProps = new File(smtpPropsFile); if (!fProps.exists()) { System.out.println("Error: no se encontró archivo " + "de configuración del servidor de correo electrónico"); return; } Properties smtpConfigProps = new Properties(); try { smtpConfigProps.load(new FileInputStream(smtpPropsFile)); } catch (IOException ex) { ex.printStackTrace(); return; } String emailToDebug = user; /*se extraen los parametros del properties como servidor, * puerto,usuario */ Properties smtpServerProps = new Properties(); String smtpHost = smtpConfigProps.getProperty("servidor"); if (smtpHost == null) { smtpHost = "localhost"; } smtpServerProps.setProperty("mail.smtp.host", smtpHost); String smtpPort = smtpConfigProps.getProperty("puerto"); if (smtpPort == null) { smtpPort = "25"; } smtpServerProps.setProperty("mail.smtp.port", smtpPort); String smtpUser = smtpConfigProps.getProperty("usuario"); if (smtpUser == null) { 59

smtpUser = "[email protected]"; } smtpServerProps.setProperty("mail.smtp.user", smtpUser); try {/*se pregunta a la tabla cfdproveedor por los datos * del del id que nos llegó como parametro*/ if (cfdp == null) { Long provId = Funcs.GetLong(id); cfdp = (Cfdproveedor) session.get(Cfdproveedor.class, provId); } /*se empieza a escribir el mensaje adjuntandole algunos parametros del archivo * properties asi como algunos que son de la tabala cfdproveedor*/ javax.mail.Session mailSess = javax.mail.Session.getInstance(smtpServerProps); mailSess.setDebug(true); MimeMessage message = new MimeMessage(mailSess); message.setFrom(new InternetAddress(smtpUser)); message.setRecipients(Message.RecipientType.TO, emailToDebug); message.setSubject(smtpConfigProps.getProperty("asunto_lib")); String body_txt = smtpConfigProps.getProperty("texto_lib"); String url = smtpConfigProps.getProperty("url_revision"); if (url == null) { url = request.getHeader("referer"); Patternpattern = Pattern.compile("^(https?://[A-Za-z0-9_\\\\.]+(:\\d+)?)/(\\S+)/(.+)$", Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(url); if (matcher.matches()) { url = matcher.group(1) + "/" + matcher.group(3) + "/revdocprov.do?op=ver"; } } body_txt = body_txt.replaceAll("%u", url + "&id=" + id + "&problema=" + problema); String folio = cfdp.getSerie() != null ? cfdp.getSerie() : ""; folio += cfdp.getFolioFiscal() != null ? cfdp.getFolioFiscal() : "error-enfolio"; String monto = cfdp.getMonto() != null ? cfdp.getMonto().toString() : "erroren-monto"; String prov = cfdp.getProveedor() != null ? cfdp.getProveedor() : "error-enproveedor"; docAttribs.get("moneda_tipoMoneda") : "error-en-moneda"; body_txt = body_txt.replaceAll("%f", folio); body_txt = body_txt.replaceAll("%m", monto); body_txt = body_txt.replaceAll("%p", prov); body_txt = body_txt.replaceAll("%ai", ""); /*aquí se le envía el texto al message y este último es enviado a la clase transporte que se 60

Encargará de enviar el mensaje a la url definida en el archivo properties */ message.setText(body_txt); Transport.send(message); } catch (Exception mailEx) { mailEx.printStackTrace(); } }

El código anterior se apoya de un archivo properties como se puede observar en el texto en negritas, que sirve para hacer parametrizable la ip del servidor, el nombre de este y el correo electrónico de la persona que envía el email. Para tal caso se crearon grupos especiales que si empiezan con RP índican al módulo de autorización que son aprobadores de facturas, lo cual índica al filtro de autorización a que ACTION debe irse, ejemplo de código que invoca al ACTION RedocProv si el grupo empieza con RP. /*Si el grupo al que pertenece el usuario empieza con RP, quiere decir que se trata de un aprobador de facturas por lo tanto solo tiene acceso a una mínima parte del sistema*/ if( uo.getGrupo ().startsWith("RP-")){ request.setAttribute("vistaProveedor", "0"); //ruta especial para aprobadores req.getContextPath() + "/revdocprov.do?op=ver&id=" + request.getParameter("id") + "&problema=" + request.getParameter("problema"); System.out.println("Filtro: grupo " + uo.getGrupo()); res.sendRedirect(redirect); return; }

Como se puede observar en el código anterior, se redirige al ACTION Revdocprov que se encargará de llenar los datos y enviar la información a un .jsp.

Función Aprobal() Si el resultado de la selección es distinto del problema 1, entonces se llama a la función Aprobal() que se encarga, de cambiar los estatus del comprobante dependiendo del problema elegido así como de enviar un email a un aprobador para dar seguimiento al problema que presento la factura, a su vez también llena un log donde se describe quien realizo el cambio de estatus, fecha, hora de lo suscitado, ejemplo véase el siguiente código. 61

public boolean Aprobal(String id, String prevStat) { /*Función encargada de cambiar a distintos estatus * el docto de cfdproveedor*/ COFIDIConfig cofidiInst = COFIDIConfig.getInstance(logger); Session session = HibernateSessionFactory.getSession(); String catalog = cofidiInst.getDB(); String schema = HibernateSessionFactory.getConfiguration().getProperty("default_schema"); TransACTION tx = null; boolean actualiza = false; String problema = request.getParameter("problemas");//No. de problema String aprobadores = request.getParameter("aprobadores");//email seleccionado if (aprobadores != null) { aprobadores = aprobadores.trim(); } String email = request.getParameter("email");//email escrito if (email != null) { email = email.trim(); } boolean statusChanged = false; Pattern emailPat = Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[AZ]{2,4}$", Pattern.CASE_INSENSITIVE); try { long cfdp_id = Funcs.GetLong(id);/*id del documento proviene de * la tabla cfdproveedor*/ tx = session.beginTransACTION(); /*query a cfdproveedor donde los registros obtenidos son los * correspondientes al id anterior*/ Cfdproveedor cfdp = (Cfdproveedor) session.get(Cfdproveedor.class, cfdp_id); /*si problema es 2,5,7 pasa a estatus 06 y se extrae el email * de la tabla cfdmateriales del campo planta y si existe el * correo se envía un email a este notificando el problema para * que este decida qué hacer con la factura y por default todo es * guardado en cfdproveedorlog a través de la función LogMsg.proveedor*/ if (problema.equals("2") || problema.equals("5") || problema.equals("7")) { statusChanged = HandleStatus.changeStatus(session, id, prevStat, "06", request); if (statusChanged) { System.out.println("planta"); String pregunta = "select mat.EmailAprobador from " + catalog + "." + schema + ".CFDApproversMateriale mat, " + catalog + "." + schema + ".CFDProveedor pro " + "where rtrim(mat.planta)=substring(pro.referencia,1,2) " + "and pro.ID=:idd"; 62

String correop = ""; Iterator cor = session.createSQLQuery(pregunta) .addScalar("EmailAprobador", Hibernate.STRING) .setParameter("idd", id).list().iterator(); while (cor.hasNext()) { correop = cor.next().toString(); } Funcs.notificaCfdAprobador(session, cfdp, request, true, correop, id, problema); LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: APPROVAL QUEUE", request, true, "06"); LogMsg.proveedor(session, cfdp_id, leyendaPro(session, catalog, schema, problema), request, true, "06"); } }/* Si el problema es 3,6,8,4,9 o 10 el estatus pasara a 06 * y se enviará un email al aprobador siempre y * cuando variable aprobador sea comparada y encontrada * en la tabla cfdaprobadores caso contrario si no se * encontró nada en la tabla cfdaprobadores entonces se * toma la variable email y se valida que sea cumpla las * condiciones para que sea un correo electrónico valido y a este correo se enviará el email pero el status cambiara a 04 caso contrario se envía la variable aprobadores*/ else if (problema.equals("3") || problema.equals("6") || problema.equals("8") || problema.equals("4") || problema.equals("9") || problema.equals("10") || problema.equals("11")) { boolean aprobador_email_ok = false; Matcher mtch = emailPat.matcher(aprobadores); if (mtch.find()) { int emailCount = ((Long) session.createQuery("select count(*) from Cfdaprobadores where correo=:c").setParameter("c", aprobadores).uniqueResult()).intValue(); if (emailCount > 0) { aprobador_email_ok = true; } } if (aprobador_email_ok) { statusChanged = HandleStatus.changeStatus(session, id, prevStat, "06", request); if (statusChanged) { Funcs.notificaCfdAprobador(session, cfdp, request, true, aprobadores, id, problema); LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: APPROVAL QUEUE", request, true, "06"); LogMsg.proveedor(session, cfdp_id, leyendaPro(session, catalog, schema, problema), request, true, "06"); LogMsg.proveedor(session, cfdp_id, "Email enviado a: " + aprobadores, request, true, "06"); 63

} } else { mtch = emailPat.matcher(email); if (mtch.find()) { statusChanged = HandleStatus.changeStatus(session, id, prevStat, "04", request); if (statusChanged) { String addInfo = request.getParameter("correoadtxt"); Funcs.notificaCfdAprobadorX(session, cfdp, request, true, email, id, problema, addInfo); LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: Problem Invoice", request, true, "04"); LogMsg.proveedor(session, cfdp_id, leyendaPro(session, catalog, schema, problema), request, true, "04"); LogMsg.proveedor(session, cfdp_id, "Email enviado a: " + email, request, true, "04"); } } else { statusChanged = HandleStatus.changeStatus(session, id, prevStat, "06", request); if (statusChanged) { Funcs.notificaCfdAprobador(session, cfdp, request, true, aprobadores, id, problema); LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: APPROVAL QUEUE", request, true, "06"); LogMsg.proveedor(session, cfdp_id, leyendaPro(session, catalog, schema, problema), request, true, "06"); LogMsg.proveedor(session, cfdp_id, "Cuenta de correo no válida: {" + Funcs.GetString(email) + "} no se enviará correo", request, true, "04"); } } } }/*Problemas restantes diferentes de 1 pasaran a estatus * 04 y no se enviará email solo serán guardados * sus datos en la tabla cfdproveedorlog */ else { statusChanged = HandleStatus.changeStatus(session, id, prevStat, "04", request); if (statusChanged) { LogMsg.proveedor(session, cfdp_id, "Estatus del documento cambiado a: PROBLEM INVOICE", request, true, "04"); LogMsg.proveedor(session, cfdp_id, leyendaPro(session, catalog, schema, problema), request, true, "04"); } } if (statusChanged) { actualiza = true; } tx.commit(); 64

} catch (HibernateException ex) { ex.printStackTrace(); ex.getCause(); } finally { session.close(); } return actualiza; }

Elemento Archivos Adjuntos Otro elemento del menú es Archivos Adjuntos, el cual sirve para mostrar los archivos que están relacionados con este documento y poder descárgalos de forma sencilla. Para que se puedan visualizar los documentos que están relacionados mediante el ID de proveedor, en un contener, es necesario escribir el siguiente código HTML que después será contenido en un objeto de YUI 2.
65

Al igual que en la función PROBLEM INVOICE, el código anterior esta en un contenedor de YUI2 que es llamado a partir de la siguiente función. function archivosAdjuntos(){ var dlgfrm_adj = document.forms["dlgadj"];//nombre del form dlgfrm_adj["dpd_prov"].value = oRecord.getData("proveedor");//nombre proveedor dlgfrm_adj["dpd_doc"].value = oRecord.getData("serie") +oRecord.getData("folioFiscal"); //función que envía los parámetros al servlet YAHOO.docs_prov.adj.dataSource.sendRequest("tb=dp_adj&id=" +oRecord.getData("id"),adjCallback); //función que muestra la ventana de dialogo con los archivos // a descargar YAHOO.docs_prov.container.dialog_adj.show(); }

Ejemplo del contenedor YUI2, véase el siguiente código. //contenedor que pinta ventana de dialogo YAHOO.docs_prov.container.dialog_adj = new YAHOO.widget.Dialog("dialog_adj", {//propiedades de la ventana de dialogo width : "20em", fixedcenter : true, visible : false, modal: true, constraintoviewport : true, buttons : [ {text:btn_lang.cerrar,handler:handleCancelDlgNR} ] });

Este elemento hace una llamada al servlet para que llene el datatable con los reportes que estén relacionados con el id de cfdproveedor. //comparación de parámetro para realizar tarea de adjuntar archivos if (table.equals("dp_adj")) { /*La clase CFDProveedorArchivosDto es la encargada * de preguntar a la bd si un determinado proveedor * tiene archivos adjuntos*/ CFDProveedorArchivosDto archivosdto = new CFDProveedorArchivosDto(); /*Cabeceras regresan al contenedor de yui los *archivos que podrán ser descargados*/ response.setContentType("application/json"); response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate,postcheck=0, pre-check=0, max-age=0"); 66

response.setHeader("Pragma", "no-cache"); response.setHeader("Expires", "Thu, 01 Jan 1970 00:00:00 GMT"); out.println(archivosdto.findById(id)); out.close(); System.out.println("HandleStatus::processRequest::" + (table == null ? "NTBL" : table) + "}"); return; }

Como se puede observar se creó una clase DTO que se encarga de traer los atributos del archivo, como el id, extensión y tamaño para formar una cadena tipo JSON que será interpretada por el código de javascript para mostrar los datos de los archivos a descargar, ejemplo de código de la clase CFDProveedorArchivosDto. /*Clase que pregunta a la bd si existe archivos adjuntos de determinado proveedor*/ CFDProveedorArchivosDao archivosdao = new CFDProveedorArchivosDao(); List lista = archivosdao.findById(id);/*método que realiza la pregunta y regresa una lista de archivos*/ /*Se crea un string buffer donde se escribirá los atributos de la anterior lista*/ StringBuilder sb = new StringBuilder(); sb.append ( "{\"ResultSet\":{"); sb.append (String.format ("\"totalResultsAvailable\":%d,",lista.size())); sb.append (String.format ("\"totalResultsReturned\":%d,",lista.size())); sb.append ( "\"firstResultPosition\":1,\"Result\":["); //la lista es iterada para sacar los atributos //de los objetos que contiene la lista Iterator it = lista.iterator(); int icount = 0; while( it.hasNext ()){ CfdproveedorArchivos cfdProvArch = (CfdproveedorArchivos) it.next(); if (icount++ > 0) { sb.append(","); } sb.append(String.format("{\"id\":\"%d\"", cfdProvArch.getId().getId())); sb.append(String.format(",\"consecutivo\":\"%d\"", cfdProvArch.getId().getConsecutivo())); 67

sb.append(String.format(",\"extension\":\"%s\"", cfdProvArch.getExtension())); Double dSize = cfdProvArch.getTamaprox(); String strSize = "1 Kb"; if (dSize > 1000000) { strSize = String.format("%.1f Mb", dSize / 1000000); } else if (dSize > 1000) { strSize = String.format("%.1f Kb", dSize / 1000); } sb.append(String.format(",\"tamaprox\":\"%s\"}", strSize)); } sb.append ( "]}}"); //por último se retorna todo el string buffer //con la información del archivo return sb.toString ();}

En el código en negritas se puede ver como se hace una instancia a una clase que funge como DAO, es decir solo hace la llamada a la base de datos y regresa su información ejemplo de la función findById( ). public List findById(String id) { Session session = HibernateSessionFactory.getSession(); TransACTION tx = null; try { tx = session.beginTransACTION(); //query a tabla CfdproveedorArchivosStd para traer //lo archivos relacionados con determinado id de proveedor //para después guardarlos en una lista que será retornada List lista =(List) session.createCriteria(CfdproveedorArchivosStd.class) .add(Restrictions.eq("id.id", Long.parseLong(id))) .list(); tx.commit(); return lista; } catch (HibernateException ex) { ex.printStackTrace(); ex.getCause(); } finally { session.close(); } return null; }

68

Cuando el usuario hace clic para iniciar el proceso de descarga se llama a un DownloadACTION que se encarga de extraer el archivo y la extensión de la base de datos, a su vez

la extensión tiene que pasar por un filtro, ya que solo se permite

descargar cierto tipo de formatos de archivos, después se crean las cabeceras que le dirán al navegador que se llevara a cabo una descarga así también se le índica a estas cuál será el nombre del archivo a descargar, ejemplo véase el siguiente código. String _id = request.getParameter("id");//id de proveedor String _consecutivo = request.getParameter("cons");//numero de archivo a descargar Object vistaProveedor = request.getSession().getAttribute("vistaProveedor"); boolean vistaProduccion = vistaProveedor == null || "0".equals(vistaProveedor.toString()); Session session = HibernateSessionFactory.getSession(); TransACTION tx = null; byte[] rawBytes = null; String archivoB64 = null; String mimeType = "application/octet-stream"; String fileext = ""; CfdproveedorArchivos cfdpArch = null; try { tx = session.beginTransACTION(); /*query a cfdproveedorArchivos para traer la * Información del archivo a descargar así como * el archivo en si*/ CfdproveedorArchivosId cfdpaId = new CfdproveedorArchivosId( Funcs.GetLong(_id), Funcs.GetInt(_consecutivo)); if (vistaProduccion) { cfdpArch = (CfdproveedorArchivos) session.get(CfdproveedorArchivosStd.class, cfdpaId); } archivoB64 = cfdpArch.getArchivo(); rawBytes = mx.com.ateb.utils.Base64.decode(archivoB64); /*filtro que permite la descarga de archivos con las siguientes extensiones*/ fileext = cfdpArch.getExtension().toUpperCase(); if (fileext.equals("XLS")) { mimeType = "application/vnd.ms-excel"; } else if (fileext.equals("DOC")) { mimeType = "application/msword"; } else if (fileext.equals("PPT")) { mimeType = "application/vnd.ms-powerpoint"; } else if (fileext.equals("PDF")) { mimeType = "application/pdf"; } else if (fileext.equals("JPG")) { mimeType = "image/jpeg"; } else if (fileext.equals("ZIP")) { 69

mimeType = "application/zip"; } tx.commit(); } catch (HibernateException he ){ he.printStackTrace(); if (tx != null) { tx.rollback(); } } finally { HibernateSessionFactory.closeSession(); } response.reset (); //cabeceras encargadas de la descarga del archivo response.setHeader ("Content-disposition", "attachment; filename=\"" + _id + "_" + _consecutivo + "." + fileext + "\""); response.setContentLength (rawBytes.length); return new ByteArrayStreamInfo(mimeType, rawBytes);

Reportes DELPHI El siguiente código HTML representa la pestaña Reportes contenida en el módulo filtro de búsqueda de COFIDI DELPHI. 71

New Document to Invoice Processed 70

Ageing on Resolution Document Processed Trend Purchase Order Cycle Time Blocked Billing Resolution Work State Wise Purchase Order Review Auditor Processed, Rejected or Cancelled
:
:
: MEXICO USA BRAZIL COLUMBIA ARGENTINA NICARAGUA HONDURAS SEOUL
:
:


Como se puede observar en el código en negritas la etiqueta

contiene un

evento onChange( ) este llama a la función habilitar(), que se encarga de mostrar las pestañas necesarias dependiendo el reporte elegido , esto con la finalidad de tomar los parámetros que elija el usuario de las pestañas activas, ejemplo véase el siguiente código. function habilitar(){ //función que muestra y oculta pestañas //habilita y deshabita cajas de texto 72

document.getElementById("emp").style.display=""; document.getElementById("tipo").style.display=""; document.getElementById("cli").style.display=""; document.getElementById("est").style.display=""; document.getElementById("fec").style.display=""; document.getElementById("pais").disabled=true; document.getElementById("plan").disabled=true; document.getElementById("plan").value=""; document.getElementById("loc").disabled=true; document.getElementById("loc").value=""; document.getElementById("dias").disabled=true; document.getElementById("dias").value=""; document.getElementById("usuarios").disabled=true; document.getElementById("usuarios").value=""; //la variable reporte contiene el reporte elegido de //la lista var reporte=document.getElementById("repoid").value; if(reporte==1||reporte==17){ document.getElementById("tipo").style.display='none'; document.getElementById("cli").style.display='none'; } if(reporte==2 || reporte==3 || reporte==4 || reporte==8 || reporte==9 || reporte==10 || reporte==11 || reporte==12 || reporte==13 || reporte==15 ){ document.getElementById("tipo").style.display='none'; document.getElementById("cli").style.display='none'; document.getElementById("est").style.display='none'; if(reporte==4){ document.getElementById("loc").disabled=false; } if(reporte==12){ document.getElementById("pais").disabled=false; document.getElementById("plan").disabled=false; } if(reporte==3 || reporte==10 ){ document.getElementById("dias").disabled=false; if(reporte==10){ document.getElementById("usuarios").disabled=false; } } } if(reporte==5){ document.getElementById("est").style.display='none'; document.getElementById("cli").style.display='none; } } 73

Para el que el usuario pueda visualizar los reportes que ya han sido generados por .NET, se creó una liga donde se muestran todos los reportes al cuál este tiene permiso. Cuando hacen clic en el link Reportes inmediatamente les muestra los reportes que ya han sido generados, pero en forma de link, esto porque desde esta aplicación el usuario los puede descargar. Por lo tanto estas ligas llaman aun DownloadACTION que se encarga de revisar la tabla CfdfileReport donde el proceso de .NET guarda el archivo generado, para después extraer el archivo y pasarlo por cabeceras que indican al navegador que se trata de un archivo que va hacer descargado ejemplo de esto ver el siguiente código. Long repId = Funcs.GetLong(request.getParameter("id"));//id del reporte Session session = HibernateSessionFactory.getSession(); TransACTION tx = null; try { tx = session.beginTransACTION(); /*De acuerdo al id del reporte que se haya generado a partir de dar clic en el link se buscara en la tabla cfdfilereport para enviarlo a las cabeceras de respuesta*/ CfdfileReport reporte = (CfdfileReport) session.createCriteria(CfdfileReport.class) .add(Restrictions.eq("id", repId)) .uniqueResult(); if (reporte != null) { response.reset(); /*El archivo encontrado en la tabla cfdfilereport es enviado * a las cabeceras para su descarga*/ response.setHeader("Content-Disposition", "attachment; filename=\"CFDRep" + repId.toString() + ".xls\""); byte[] fileContent = reporte.getArchivo(); return new ByteArrayStreamInfo("application/vnd.ms-excel", fileContent); } tx.commit(); } catch (HibernateException ex) { tx.rollback(); ex.printStackTrace(); ex.getMessage(); } finally { session.close(); } 74

return new ByteArrayStreamInfo("text/javascript", "se ha generado un error".getBytes()); }

75

Glosario Adenda: La adenda es un elemento de la factura electrónica, que el SAT ha puesto a disposición de las empresas para que puedan agregar al comprobante datos que no son relevantes en términos fiscales, pero que comercialmente sí lo son, por ejemplo clave de proveedor, número de orden de compra, números de serie de los productos, el lugar de entrega, etc. Es importante mencionar que el contenido de la Adenda NO es considerado en la generación de la Cadena Original ni en el Sello Digital del CFD, es decir, el contenido de la Adenda no ―participa‖ en el procesamiento de la información que le da validez al CFD. AIX: Es un sistema operativo UNIX abierto que permite ejecutar las aplicaciones deseadas en cualquier hardware y servidores IBM UNIX. Aplicación: Programa informático que permite a un usuario utilizar una computadora con un fin específico. Las aplicaciones son parte del software de una computadora, y suelen ejecutarse sobre el sistema operativo. Una aplicación de software suele tener un único objetivo: navegar en la web, revisar correo, explorar el disco duro, editar textos, jugar (un juego es un tipo de aplicación), etc. Una aplicación que posee múltiples programas se considera un paquete. Archivo: Es un grupo de datos estructurados que son almacenados en algún medio y pueden ser usados por las aplicaciones. AS/400: Servidor de IBM pensado para pequeñas empresas y usuarios departamentales. Sistema multiusuario con una interfaz controlada mediante menús, que utiliza terminales y un sistema operativo basado en bibliotecas, OS/400. B2B: Business-to-business es la transmisión de información referente a transacciones comerciales electrónicamente, normalmente utilizando tecnología como la Electronic Data Interchange (EDI),

presentada

a

finales

de

los

años

1970

para

electrónicamente documentos tales como pedidos de compra o facturas.

enviar

Forma de

comercio electrónico en donde las operaciones comerciales son entre empresas y no con usuarios finales. Base de datos: Es un sistema que almacena datos que están relacionados. BCPS: es un tipo de software ERP. La diferencia básica es que los BPCS es un tipo específico de ERP realizado por una empresa de software de negocios llamada Infor. Planificación financiera, fabricación y distribución de planificación y gestión de la cadena de suministro son características comunes de software BPCS y ERP. Este tipo de software también puede incluir características para ayudar a una base de datos 76

administrar negocios de información, que puede ser útil para organizar los datos del cliente. Clase: Es una plantilla que define las variables y los métodos que son comunes para todos los objetos de un cierto tipo. Comercio Electrónico: Consiste en realizar electrónicamente transacciones comerciales; es cualquier actividad en la que las empresas y consumidores interactúan y hacen negocios entre sí o con las administraciones por medios electrónicos. Control 2000: E s un software donde sus módulos apoyan a las áreas administrativas, contables y fiscales de una empresa. CRM: Customer Relationship Management, gestión de las relaciones con el cliente. El CRM no es una nueva filosofía de trabajo u organización, sino el resultado de unir las antiguas técnicas comerciales de los pequeños establecimientos, con la tecnología de la información. DCOM: (Distributed Component Object Model - Modelo de Objetos de Componentes Distribuidos) es una tecnología de Microsoft que permite desarrollar componentes de software distribuidos sobre múltiples computadoras que se intercomunican. DCOM extiende el modelo COM de Microsoft. EDI: electrónicos. Se usa para transferir documentos electrónicos o datos de negocios de un sistema computacional a otro. El intercambio electrónico de datos puede realizarse en distintos formatos: EDIFACT, XML, ANSI ASC X12, TXT, etc. ERP’S: universalidad, estandarización e interfaces con otras aplicaciones. Son sistemas abiertos y en la mayoría de los casos multiplataforma. Factura: Es un documento de carácter administrativo que sirve de comprobante de una compraventa de un bien o servicio y, además, incluye toda la información de la operación. FTP: File Transfer Protocol es un medio específico de conexión de un Sitio web para cargar y descargar ficheros. FTP fue desarrollado durante los comienzos de Internet para copiar ficheros de una computadora a otra. Función: Es una subrutina que contiene una o más sentencias que efectúan una tarea determinada. Hipervínculo: Es un enlace, normalmente entre dos páginas web de un mismo sitio, que también puede apuntar a una página de otro sitio web, a un fichero, a una imagen, etc. Para navegar al destino al que apunta el enlace, hemos de hacer clic sobre él. También se conocen como hiperenlaces, enlaces o links.

77

HTML: Es un lenguaje de programación que se utiliza para el desarrollo de páginas de Internet. Se trata de la sigla que corresponde a HyperText Markup Language, es decir, Lenguaje de Marcas de Hipertexto, que podría ser traducido como Lenguaje de Formato de Documentos para Hipertexto. HTTP: datos, traducción y otras funcionalidades. Toda la información que opera en la Web mediante este protocolo es identificada mediante el URL o dirección. Infor: Es un ERP que abarca, desde la fase de automatización hasta la de colaboración y ejecución, e incluyen funciones no sólo para cada sector, sino también para los recursos y procesos específicos de cada compañía. Interfaz: Esta noción se utiliza para nombrar a la conexión física y funcional entre dos sistemas o dispositivos. Internet: Es la colección mundial de computadoras conectadas entre sí mediante una red de canales de comunicación. La tecnología de comunicaciones consiste en una gran variedad de tecnologías: satélites, microondas, fibra óptica y alambre de cobre. Algunas redes son privadas y otras públicas. Millones de computadoras están conectadas entre si y pueden intercambiar información. Lenguaje de programación: Es una secuencia de comandos que genera un código de instrucciones que nos permite comunicarnos con una computadora. Librerías: Es una colección de piezas de programa que ya están escritas, las cuáles se guardan en archivos. Mainframe: Computadora grande, poderosa y costosa utilizada principalmente en empresas que necesitan procesar gran cantidad de datos o soportar gran cantidad de usuarios. MAPICS: es software ERP para controlar las operaciones de las empresas manufactureras. Método: Son las acciones que puede ejecutar el objeto. MFG/PRO: proporciona soluciones ERP completas gracias al empleo de bases de datos Oracle o Progress y su aplicación en la mayoría de los entornos UNIX, Windows, y Windows NT. El software basado en objetos, con aplicaciones para la gestión de fabricación, distribución, finanzas y servicio/soporte al cliente, presenta una interfaz gráfica del usuario (Graphical User Interfdace GUI) y soporta tanto la implementación Host (modo caracter) como la implementación cliente/servidor, en entornos distribuidos. MVC: Es un patrón de diseño que especifica cómo debe ser estructurada una aplicación, las capas que van a componer la misma y la funcionalidad de cada una. Según este 78

patrón, la capa intermedia de una aplicación Web puede ser dividida en tres grandes bloques funcionales: Controlador, Vista y Modelo. Nota de Cargo: Documento a través del cual se hace saber al Deudor el haber realizado un cargo en su cuenta. Se utiliza cuando no es apropiado emitir una factura. Nota de Crédito: Son comprobantes de índole contable y tributaria, que sirven para sustentar el otorgamiento de un descuento o bonificación, anulación total o parcial de la devolución de bienes vendidos. Objeto: Es la representación en un programa de

un concepto, y contiene toda la

información necesaria para abstraerlo: datos que describen sus atributos y operaciones que pueden realizarse sobre los mismos. PeopleSoft (JDE): Edwards World Solution Empresa o JD Edwards, abreviado JDE, era un sistema de planificación de recursos empresariales (ERP), compañía de software. Programa: Es una secuencia de instrucciones que deben seguirse, empezando con la primera y avanzando de una en una hasta que se complete la secuencia. Protocolos: Es una serie de reglas que nos permiten que los dispositivos se comuniquen entre sí. Recibo de arrendamiento: Es un contrato en que una parte (arrendador) permite el uso de un objeto mueble o inmueble y otra (arrendatario) que paga un precio (canon). El contrato de arrendamiento se hace a través de un contrato escrito o verbalmente. Recibo de honorarios: Son comprobantes de pago que deben entregar las personas que ejercen una profesión, oficio, ciencia, o arte en forma independiente al momento de cobrar sus honorarios por los servicios prestados. Retail Pro: es una de las soluciones para negocios detallistas más avanzadas y robustas en todo el mundo. SAE: Controla el ciclo de todas las operaciones de compra-venta de la empresa como: inventarios, clientes, facturación, cuentas por cobrar, vendedores, compras, proveedores y cuentas por pagar; automatizando eficientemente los procesos administrativos y asegurando el cumplimiento de las disposiciones fiscales. Permite conectar de manera remota las sucursales de la empresa. Ofrece reportes, estadísticas, gráficas y consultas de alto nivel que colaboran en la oportuna toma de decisiones y desarrollo de estrategias comerciales. SAP: Sistemas, Aplicaciones y Productos en Procesamiento de datos. EL nombre SAP es al mismo tiempo el nombre de una empresa y el de un sistema informático. Este sistema

comprende

muchos

módulos

completamente

integrados,

que

abarca 79

prácticamente todos los aspectos de la administración empresarial. Cada módulo realiza una función diferente, pero está diseñado para trabajar con otros módulos. Servidor: En redes, computadora central en un sistema de red que provee servicios a otras computadoras. En internet, los servidores son los proveedores de todos sus servicios, incluyendo la WWW

(las páginas web), el FTP, el correo electrónico,

los grupos de noticias, etc. Servlets: Pequeño programa que corre en un servidor. Por lo general son aplicaciones Java que corren en un entorno de servidor web. Esto es análogo a una aplicación Java que corre en un navegador. Sistema operativo: Es el conjunto de programas que se cargan y ejecutan automáticamente cuando la computadora se enciende. Sistema

propietario:

el software propietario (también

llamado privativo, de

código

cerrado o software no libre) es cualquier programa informático en el que el usuario tiene limitaciones para usarlo, modificarlo o redistribuirlo (esto último con o sin modificaciones). SMTP: Protocolo simple de transferencia de correo (SMTP) está diseñado para la transferencia de correo eficiente y confiable. Se utiliza ampliamente en las instalaciones de instituciones gubernamentales y educativas y también es el estándar utilizado por Internet para transferencia de correo. SUN Solaris: Solaris es un sistema operativo de tipo Unix desarrollado desde 1992 inicialmente por Sun Microsystems y actualmente por Oracle Corporation como sucesor de SunOS. UDP: User Datagram Protocol (UDP) es un protocolo del nivel de transporte basado en el intercambio de datagramas (Encapsulado de capa 4 Modelo OSI). UNIX: Es un sistema operativo portable, multitarea y multiusuario; desarrollado, en principio, en 1969, por un grupo de empleados de los laboratorios Bell deAT&T, entre los que figuran Ken Thompson, Dennis Ritchie y Douglas McIlroy. URL: Uniform Resource Locator, es una secuencia de caracteres, de acuerdo a un formato modélico y estándar, que se usa para nombrar recursos en Internet para su localización o identificación, como por ejemplo documentos textuales, imágenes, vídeos, presentaciones digitales, etc. XHTML: Siglas del inglés Extensible HyperText Markup Language. XHTML es básicamente HTML expresado como XML válido. Es más estricto a nivel técnico, pero esto permite que posteriormente sea más fácil al hacer cambios o buscar errores entre otro. XPPS: es un ERP orientado a proveedores del sector de automoción. 80

81

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.