Upload
lamanh
View
218
Download
0
Embed Size (px)
Citation preview
Naziha Ayachi Majait
Aplicación web para el control de proyectos en la empresa Sumainfo S.L.
Francisco José García Izquierdo
Facultad de Ciencias, Estudios Agroalimentarios e Informática
Grado en Ingeniería Informática
2012-2013
Título
Autor/es
Director/es
Facultad
Titulación
Departamento
TRABAJO FIN DE GRADO
Curso Académico
© El autor© Universidad de La Rioja, Servicio de Publicaciones, 2013
publicaciones.unirioja.esE-mail: [email protected]
Aplicación web para el control de proyectos en la empresa Sumainfo S.L.,trabajo fin de grado
de Naziha Ayachi Majait, dirigido por Francisco José García Izquierdo (publicado por laUniversidad de La Rioja), se difunde bajo una Licencia
Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported. Permisos que vayan más allá de lo cubierto por esta licencia pueden solicitarse a los
titulares del copyright.
UNIVERSIDAD DE LA RIOJA
FACULTAD DE CIENCIAS, ESTUDIOS AGROALIMENTARIOS E INFORMÁTICA
GRADO EN INGENIERÍA INFORMÁTICA
Aplicación web para el control de proyectos en la empresa
Suma Info S.L. TRABAJO FIN DE GRADO
Junio de 2013
Realizado por
Naziha Ayachi Majait
Dirigido por
Francisco José García Izquierdo
Resumen
El presente Trabajo Fin de Grado consiste en el desarrollo de una aplicación web para la
gestión de los proyectos en la empresa de servicios informáticos Suma Info S.L. Partiendo de
una aplicación web que usa la tecnología JavaServer Pages y una base de datos en Oracle, se
construirá otra nueva usando JavaServer Faces, Facelets, Richfaces, Hibernate y Spring, que
se monta sobre un nuevo modelo de datos en MySQL.
La funcionalidad de la nueva aplicación consiste en gestionar los proyectos de la empresa,
mantener los tiempos que registran los empleados para cada uno de los proyectos en los que
participan, así como los gastos y honorarios generados durante el proceso de ejecución y su
asignación a los proyectos. Además del mantenimiento del personal de la empresa y los
clientes con los que interactúa, debe gestionar todas las facturaciones realizadas para
contabilizar los gastos y honorarios producidos por los proyectos activos en la empresa.
Una de las mayores dificultades de este proyecto fue el manejo de las distintas tecnologías,
totalmente desconocidas para mí hasta el inicio del trabajo, lo que supuso un largo proceso
de formación. Uno de los principales problemas fue la integración de las tecnologías
utilizando Spring Framework, sobre todo en el caso de Hibernate. La construcción del
proyecto con Maven y la gestión de las librerías fue otro punto problemático durante el
desarrollo.
Otro aspecto clave fue comprender y aplicar todos los mecanismos que ofrece Spring Security
para garantizar la seguridad de la aplicación.
Mi mayor reto fue hacer frente a todos los problemas surgidos, desde la fase de recogida de
requisitos, pasando por el diseño de la arquitectura hasta llegar a su completa
implementación y en buscar las soluciones que más se adapten a cada caso y aplicarlas para
ver que el problema se resuelve.
El resultado obtenido es una aplicación web que amplía la funcionalidad de la antigua y que
ha sido desarrollada con una tecnología más actual que facilitará su mantenimiento y
evolución.
Abstract
The present dissertation consists of the development of a web application for the
management of projects in the company of computer services Suma Info S.L. Starting with
the web application that employs the JavaServer Pages and an Oracle database, a new
database is constructed using JavaServer Faces, Facelets, Richfaces, Hibernate and Spring,
which is assembled on a new model of data in MySQL.
The usefulness of the new application is based on the management of the projects of the
company, maintaining the time that the employees record in each one of the projects that
they take part in, as well as the expenses and the fees generated throughout the process of
execution and assignation of the projects. In addition to the maintenance of the personnel
employees, and the clients with whom they interact; it must also arrange all the billing
realized for the accountancy of the expenses and the fees produced by the active projects of
the company.
One of the most difficult aspects of this project was the handling of the diverse technology,
totally unknown to me until the beginning of the project; and this supposed a long process of
instruction. One of the main problems was the integration of technology applying Spring
Framework, principally in the case of Hibernate. The formation of the project with Maven,
and the administration of the Java libraries was another problematic point in the
development of the project.
Another key aspect was the understanding and the application of all the mechanisms that
Spring Security offers to warranty the security of the application.
My greatest challenge was tackling all the problems that emerged, from the phase of
collection of requirements, going through the design of the architecture, until reaching its
complete implementation and search for the solutions that best adapts with each case, and
their application to notice that the problem is solved.
The result obtained is a web application that extends the functionality of the former one, and
that has been established with a more modern technology that facilitates its maintenance
and evolution.
Agradecimientos
Me gustaría dar las gracias a:
Mi tutor Francisco José García Izquierdo por darme los ánimos necesarios para seguir
adelante, por sus consejos valiosos cuando más los necesitaba y por guiarme a lo largo del
proyecto.
Mis queridos padres y hermanos que me han apoyado en todo y por la confianza que han
depositado siempre en mí.
Todos mis profesores por aportarme los conocimientos necesarios para afrontar las
dificultades surgidas durante el desarrollo del proyecto.
Los integrantes de la empresa Suma Info S.L. y en especial a Juan Adanero, Eduardo Frías y
Alejandro Ochoa por su ayuda y apoyo.
Mis amigos y compañeros que han estado siempre a mi lado y por compartir los malos y
buenos momentos dentro y fuera de la universidad.
ÍNDICE
INTRODUCCIÓN ....................................................................................................................... 1
1. Visión general .......................................................................................................................................... 1
2. Objetivos del proyecto ......................................................................................................................... 2
1. ANÁLISIS ............................................................................................................................ 3
1.1. Especificación de requisitos funcionales ...................................................................................... 3
1.1.1. Gestión de usuarios y personal de la empresa ................................................................. 3
1.1.2. Mantenimiento de proyectos ................................................................................................... 4
1.1.3. Mantenimiento de tiempos ....................................................................................................... 5
1.1.4. Gestión de gastos .......................................................................................................................... 6
1.1.5. Gestión de facturas ....................................................................................................................... 6
1.1.6. Mantenimiento de los clientes ................................................................................................ 7
1.2. Especificación de los requisitos no funcionales......................................................................... 7
1.2.1. Requerimientos tecnológicos .................................................................................................. 7
1.2.2. Seguridad ......................................................................................................................................... 7
1.3. Modelo del dominio ............................................................................................................................... 8
1.3.1. Clases identificadas ...................................................................................................................... 8
1.3.2. Diagrama de clases ....................................................................................................................... 9
2. DISEÑO ............................................................................................................................ 10
2.1. Modelo de datos .................................................................................................................................... 10
2.1.1. Antiguo modelo de datos ......................................................................................................... 10
2.1.1.1. Diagrama .............................................................................................................................. 10
2.1.1.2. Entidades .............................................................................................................................. 11
2.1.1.3. Deficiencias .......................................................................................................................... 12
2.1.2. Modelo de datos actual ............................................................................................................. 13
2.1.2.1. Requisitos ............................................................................................................................. 13
2.1.2.2. Migración de Oracle a MySQL ...................................................................................... 14
2.1.2.3. Diagrama .............................................................................................................................. 14
2.1.2.4. Diferencias respecto del antiguo modelo ................................................................ 16
2.2. Arquitectura software ........................................................................................................................ 17
2.2.1. Capa de presentación ................................................................................................................ 17
2.2.2. Capa de lógica de negocio ........................................................................................................ 17
2.2.3. Capa de persistencia .................................................................................................................. 18
2.2.4. Comunicación entre las capas ............................................................................................... 19
2.3. Interfaces de usuario .......................................................................................................................... 20
2.3.1. Interfaz de login .......................................................................................................................... 20
2.3.2. Partes fijas de la interfaz ......................................................................................................... 21
2.3.3. Interfaz de páginas con listado ............................................................................................. 22
2.3.4. Interfaz de páginas con formulario ..................................................................................... 22
3. IMPLEMENTACIÓN ...................................................................................................... 23
3.1. Tecnologías empleadas ...................................................................................................................... 23
3.1.1. Maven .............................................................................................................................................. 23
3.1.2. Hibernate ....................................................................................................................................... 24
3.1.3. Richfaces ......................................................................................................................................... 25
3.1.4. Facelets ........................................................................................................................................... 25
3.1.5. Spring ............................................................................................................................................... 26
3.1.6. Informes con Jasperreports .................................................................................................... 26
3.2. Validación y conversión ..................................................................................................................... 28
3.3. Seguridad ................................................................................................................................................. 30
3.3.1. Autenticación ................................................................................................................................ 30
3.3.2. Autorización .................................................................................................................................. 33
3.4. El proceso de trabajo .......................................................................................................................... 34
3.4.1. La vista JSF ..................................................................................................................................... 34
3.4.2. El Controlador .............................................................................................................................. 35
3.4.3. El Servicio ...................................................................................................................................... 37
3.4.4. El DAO .............................................................................................................................................. 37
3.5. Pruebas ..................................................................................................................................................... 38
4. GESTIÓN DEL PROYECTO .......................................................................................... 40
4.1. Planificación inicial .............................................................................................................................. 40
4.2. Definición de tareas ............................................................................................................................. 40
4.3. Diagrama de Gantt ............................................................................................................................... 40
4.4. Resultado final ....................................................................................................................................... 42
4.4.1. Comparación entre el tiempo estimado y el real ........................................................... 42
4.4.2. Justificación de los desfases ................................................................................................... 43
4.5. Problemas afrontados ........................................................................................................................ 44
CONCLUSIONES ..................................................................................................................... 45
Posibles mejoras ............................................................................................................................................. 45
BIBLIOGRAFÍA ...................................................................................................................... 46
ÍNDICE DE FIGURAS
Figura 1: Diagrama de clases del modelo ................................................................................................... 9
Figura 2: Diagrama del antiguo modelo de datos .................................................................................. 10
Figura 3: Diagrama del modelo de datos actual ..................................................................................... 15
Figura 4: Diagrama de algunas clases de persistencia ........................................................................ 18
Figura 5: Comunicación entre DAOs ........................................................................................................... 19
Figura 6: Flujo de “añadir nuevo proyecto” ............................................................................................. 20
Figura 7: Prototipo de la interfaz de login ................................................................................................ 21
Figura 8: Prototipo del esqueleto general ................................................................................................ 21
Figura 9: Prototipo de páginas con listado ............................................................................................... 22
Figura 10: Prototipo de páginas con formulario .................................................................................... 22
Figura 11: Dependencias del proyecto ...................................................................................................... 23
Figura 12: Plantilla “jrxml” de facturas ...................................................................................................... 27
Figura 13: Ciclo de vida JSF ............................................................................................................................. 28
Figura 14: Proceso de autenticación en Spring Security .................................................................... 32
Figura 15: Proceso de trabajo en la aplicación ....................................................................................... 34
Figura 16: Descomposición de tareas ........................................................................................................ 40
Figura 17: Diagrama de Gantt ........................................................................................................................ 41
Figura 18: Gráfico de comparación de tiempos...................................................................................... 43
ÍNDICE DE TABLAS
Tabla 1: Entidades del antiguo modelo ..................................................................................................... 12
Tabla 2: Leyenda de símbolos del diagrama ER ..................................................................................... 14
Tabla 3: Comparación entre tiempos ......................................................................................................... 42
1
INTRODUCCIÓN
1. Visión general
En el presente proyecto se parte de una aplicación ya disponible y puesta en
funcionamiento para la gestión de proyectos en la empresa Suma Info S.L.
La antigua aplicación se basa en la tecnología JavaServer Pages y usa una base de datos
en Oracle. Uno de los problemas que presenta esta aplicación es que su modelo de
datos no corresponde con lo que realmente se pretende modelar, ya que sólo almacena
tablas aisladas sin ninguna interconexión. Esto puede suponer incongruencias en la
base de datos. Además de todo lo anterior, la aplicación web posee una interfaz de
usuario poco usable.
El objetivo principal de este proyecto es lograr la construcción de una nueva aplicación
que se apoya sobre un nuevo modelo de datos, que suponga una mejora en el
rendimiento respecto de la aplicación actual y que facilite su mantenimiento posterior.
El proyecto tiene su punto de partida en la redefinición de los requisitos de la nueva
aplicación y su modelo de datos. Esta fase empieza por una recolección de los
requerimientos mediante varias reuniones con el cliente.
Asentándose sobre una base sólida de análisis, en su segunda fase se diseñaron todos
los elementos necesarios para la construcción de un nuevo sistema completo que se
ajusta a las necesidades del cliente.
Después de un largo proceso de formación en todas las tecnologías que venían
impuestas por el cliente para ser usadas en la fase de desarrollo de la aplicación, con el
fin de facilitar este proceso y el mantenimiento de la nueva aplicación de gestión. La
fase de implementación empieza con el uso del estándar JavaServer Faces (JSF) que
resuelve varios problemas que se planteaban al principio, el sistema simplificado de
presentación Facelets que aporta mayor libertad al anterior en cuanto al diseño y la
librería de componentes Richfaces para dotar los componentes de capacidad Ajax sin la
necesidad de escribir ni una línea de código JavaScript y su completa integración en el
ciclo de vida JSF.
Con el uso de Spring Framework el coste de integración se ha reducido de forma
drástica. El soporte para las anotaciones que brinda esta tecnología, las nuevas
posibilidades para vincular los objetos con los que se trabaja, gracias al nuevo concepto
de inyección de dependencias y su gestión transparente para el usuario.
Si profundizamos en la arquitectura de esta aplicación, nos encontramos con el motor
de persistencia Hibernate utilizado en el mapeo Objeto Relacional. Totalmente
integrable con Spring mediante las plantillas que ofrece este último, lo que hace que la
labor del desarrollador se reduzca notablemente debido a su gestión de las conexiones
y transacciones con la base de datos.
2
Con Spring Security nace el concepto de seguridad declarativa para mantener y
alcanzar un determinado nivel de seguridad, lo que hace que la aplicación tenga una
arquitectura limpia y robusta.
Por último y como resultado final se obtiene una aplicación Web de gestión ajustada a
las necesidades del cliente, intuitiva y fácil de manejar.
Palabras clave: JavaServer Faces, Hibernate, Spring, Framework, Aplicación Web,
Spring Security, DAO, Jasperreports, Facelets, Java, autenticación, autorización, capas y
MVC.
2. Objetivos del proyecto
El proyecto consiste en el desarrollo de una aplicación web para el control de proyectos en la empresa SumaInfo S.L. utilizando las siguientes tecnologías que vienen impuestas por la misma: JavaServer Faces, Facelets, Richfaces, Hibernate, Spring y una base de datos en MySQL. Las funciones básicas de esta aplicación web se pueden resumir en: El control y mantenimiento de los proyectos activos en la empresa, la asignación de
personal a dichos proyectos y el registro de los tiempos dedicados a cada proyecto por el técnico correspondiente.
La gestión de los gastos imputados a cada proyecto. La gestión de las facturas correspondientes a cada proyecto. El mantenimiento de los clientes y el personal de la empresa. Ofrecer la posibilidad de exportación de informes de las facturaciones en formato
PDF. La aplicación debe permitir el mantenimiento de la información de forma fácil y rápida,
así como tener una infraestructura de usuarios y roles para controlar el acceso y
garantizar un determinado nivel de seguridad.
3
1. ANÁLISIS
1.1. Especificación de requisitos funcionales
A la vista de los resultados obtenidos de las reuniones mantenidas con el cliente, he
decidido especificar el funcionamiento de la aplicación dividido en seis partes
agrupadas por áreas:
Gestión de usuarios y personal de la empresa.
Mantenimiento de proyectos.
Mantenimiento de tiempos.
Gestión de facturas.
Gestión de gastos.
Mantenimiento de los clientes.
Antes de empezar a describir los tipos de usuarios de la aplicación y las funciones de
cada uno, debo mencionar tres operaciones que son comunes para cualquier usuario,
independientemente de su rol:
Identificarse en la aplicación mediante el usuario y la contraseña: todo usuario
debe ser identificado por la aplicación antes de proceder a realizar cualquier
operación. La identificación de un usuario le permite adquirir los privilegios
con los que puede interactuar con la aplicación web.
Salir de la aplicación y cerrar la sesión iniciada por el usuario: para
garantizar la seguridad evitando de esta manera posibles incidentes, se
recomienda al usuario que cierre su sesión cada vez que desea salir de la
aplicación. En caso de que no se lleve a cabo esta operación, el sistema deberá
garantizar la invalidación de la sesión pasado un cierto período de tiempo.
Cambiar contraseña: una vez que se identifica el usuario, el sistema debe
permitirle cambiar su contraseña antigua por una nueva.
1.1.1. Gestión de usuarios y personal de la empresa
La aplicación permitirá una gestión de usuarios que abarcará las funcionalidades de dar de alta a un nuevo usuario, darle de baja y consultar o modificar sus datos personales.
Los usuarios de dicha aplicación serán todos los empleados de la empresa,
distinguiéndose entre usuarios con privilegios (responsables) y el resto de usuarios
que serán los técnicos. Estos últimos podrán adquirir dicho rol siempre que hayan
sido dados de alta en el sistema por un usuario responsable.
4
Usuario técnico: podrá llevar una gestión de sus tiempos, que consiste en registrar el tiempo que dedica a un proyecto y modificar o eliminar dichos registros. Por otra parte consultar la ficha de los proyectos de la empresa y mantener sus gastos.
Usuario responsable: este usuario gozará de los privilegios de
administrador del sistema y con los cuales podrá acceder a las funcionalidades del usuario técnico y además llevar a cabo la gestión de usuarios, el mantenimiento de proyectos, así como la gestión de facturas.
Para dar de alta a un empleado se debe recoger, su nombre, apellidos, usuario y contraseña para acceder a la aplicación y asignarle un rol (técnico o responsable). Dado que no es imprescindible recoger el DNI o cualquier otro documento identificativo del empleado, para ello, se le asigna un código único en el sistema.
Un usuario responsable podrá modificar todos los datos de un empleado excepto su
código identificativo, así como darle de baja introduciendo la fecha en la que tuvo
lugar dicha baja.
Una vez que se da de alta a un empleado en el sistema, se le debe asignar una
categoría con la que puede operar dentro del período de un año (gerente,
responsable, analista, programador, etc.). Esta será elegida de una lista de categorías
predeterminadas. Debemos distinguir entre esta asignación y la que se realiza dentro
del ámbito de un proyecto. Los usuarios responsables serán los encargados de
gestionar estas asignaciones de categorías, pudiendo modificar o eliminar
asignaciones previas.
Las tarifas de un empleado dependen de la categoría que tenga asignada, por lo que se
debe llevar un registro de la categoría, el importe de la tarifa y el año de la asignación.
Los usuarios responsables podrán consultar los datos de cualquier empleado dado de
alta en la aplicación, como el nombre, los apellidos y el usuario, así como consultar
las categorías y tarifas de cada empleado.
1.1.2. Mantenimiento de proyectos
La aplicación les permitirá a los usuarios responsables gestionar los proyectos de la
empresa, para activar un nuevo proyecto o modificar uno existente y consultar el
histórico de todos los proyectos.
Cada proyecto tiene un identificador único que generará la aplicación
automáticamente antes de su almacenamiento. Éste identificador estará compuesto
por el año, código del cliente y un número correlativo. No puede haber dos proyectos
con el mismo identificador en el sistema.
La denominación, plataforma de desarrollo, cliente, fecha propuesta y tipo de
proyecto (interno, externo, facturable, etc.), son datos obligatorios para la activación
de un nuevo proyecto. Además de éstos datos se pueden añadir otros como la fecha
de aprobación del proyecto, la fecha prevista para la finalización y la fecha de inicio.
5
El número de personas se calculará en función de los técnicos que se vayan asignando
al proyecto y el número de horas totales en función del tiempo que registran estos
últimos.
La plataforma de desarrollo y el tipo de proyecto se eligen de una lista. Por ello, se
permitirá a los usuarios responsables el mantenimiento de las distintas plataformas
de desarrollo utilizadas en la empresa y los tipos de proyecto, accediendo a su
creación, modificación y borrado. De cada plataforma o tipo de proyecto se almacena
su código y denominación.
Será posible la modificación de los datos de un proyecto activo en la empresa, aunque
no se permitirá modificar su identificador.
Los usuarios con rol responsable podrán consultar los proyectos de la empresa.
Empezando por ver sus datos básicos (fecha de propuesta, identificador del proyecto,
descripción, el cliente, la plataforma utilizada y si está finalizado) hasta ver todos los
empleados que participan en su realización y los tiempos previamente registrados
por cada empleado.
Les permitirá a los usuarios responsables la asignación de nuevos técnicos para la
realización de un proyecto. En este caso, debe indicar la categoría con la que operará
dentro del marco de ese proyecto. Un técnico puede operar con distintas categorías
dentro del mismo proyecto (Ej.: un empleado puede ser el responsable y analista de
un proyecto).
Los usuarios identificados como técnicos por la aplicación, sólo tendrán permisos
para acceder a los datos básicos de un proyecto, por lo tanto, no podrán ver los
empleados asignados ni los tiempos que hayan registrado.
1.1.3. Mantenimiento de tiempos
Será posible llevar un control de los tiempos que dedican los empleados a cada
proyecto, registrando una pequeña descripción de la tarea realizada, el tiempo
invertido (en horas), además de la fecha, el número de orden y el tipo de trabajo
realizado elegido de una lista. Excepto el tipo de trabajo, todos los datos son
obligatorios para añadir un nuevo registro de tiempo. Los usuarios responsables se
encargan de mantener los distintos tipos de trabajo almacenando su código y
denominación, que posteriormente podrán modificar o eliminar.
El número de orden será generado automáticamente por la aplicación y dependerá
del número de registros del técnico para un mismo proyecto.
Sólo podrán registrar tiempos en proyectos activos. Estos registros se distinguen por
la fecha, el técnico y el número de orden. Por norma de la empresa a cada tarea se le
debe dedicar como mínimo una media hora.
Cada usuario podrá acceder a sus registros de tiempo y modificarlos o proceder a su
borrado si es necesario. No se permite modificar la fecha del registro ni el número de
6
orden. La aplicación permitirá a cualquier usuario registrado la consulta de la fecha, el
proyecto, la actividad realizada y el tiempo invertido (en horas) de todos sus tiempos.
1.1.4. Gestión de gastos
Cada usuario deberá registrar sus gastos personales en los que se incurre durante el
ciclo de vida de un proyecto en el que participa.
Podrá imputar sus gastos a algún proyecto concreto. De cada gasto se recoge la fecha,
el número de orden, el tipo de gasto del que se trata (gastos de hotel, transporte, etc.),
el proyecto y por último el importe y una breve descripción. No se pueden imputar
gastos a proyectos que se consideran finalizados.
El número de orden será generado automáticamente por la aplicación y dependerá
del número de registro de gastos del técnico para un mismo proyecto.
El tipo de gasto se elige de una lista que almacena distintos tipos de gastos externos al
proyecto considerados por la empresa. Los usuarios responsables serán los
encargados de mantener esta lista actualizada insertando nuevos registros, y
modificando o eliminando registros de la misma.
Cada usuario tiene total acceso a sus gastos para modificar o eliminar sus registros,
excepto la fecha de creación de los mismos.
Los usuarios podrán visualizar todos los gastos y consultar su fecha de creación,
proyecto al que pertenecen, la descripción y su importe.
1.1.5. Gestión de facturas
Con el fin de llevar a cabo una contabilidad a nivel de aplicación de algunos de los
gastos generados por los proyectos que se llevan a cabo en la empresa, la aplicación
deberá permitir a los usuarios responsables la facturación de los gastos imputados a
un proyecto.
En este caso, podrán facturar gastos que hayan registrado e imputado a un proyecto
concreto (de transporte, viajes, etc.). Por otra parte, podrán incluir honorarios, es
decir, gastos generados por el desarrollo del proyecto (horas de programación,
análisis, etc.).
Además del importe total de todos los gastos, cada factura debe incluir un número
único, la fecha de su creación, el proyecto y el impuesto sobre el valor añadido (IVA)
correspondiente a la operación
El número de una factura será generado automáticamente por la aplicación y
compuesto por un número correlativo dependiente de las facturaciones realizadas al
cliente y el año en curso.
7
De los honorarios incluidos en una factura, se recoge la tarea realizada que se elige de
la lista de tipos de trabajo realizado. Se recoge también la fecha de registro, el número
de horas dedicadas, el técnico que realizó la tarea, el importe que se calcula a partir de
las horas y la tarifa del técnico, la factura con la que se relaciona el honorario y una
descripción más detallada del trabajo que se ha llevado a cabo. Un usuario
responsable podrá acceder al borrado de los honorarios incluidos en una factura.
Se consideran datos obligatorios para la creación de una factura, su fecha de creación,
número y el proyecto que se está facturando.
Permitirá a los usuarios responsables la modificación y borrado de las facturas que
haya generado anteriormente. No se permite la modificación del número de factura ni
la fecha de su creación.
Un usuario responsable podrá visualizar todas las facturaciones realizadas y ver sus
detalles, así como generar informes con los mismos en formato PDF Los datos que se
pueden consultar de cada factura son: la fecha, proyecto, gastos incluidos, honorarios
y el importe total.
1.1.6. Mantenimiento de los clientes
Permitir a los usuarios responsables mantener todos los clientes relacionados con la
empresa. Mediante esta funcionalidad podrán acceder a la consulta de sus datos,
añadir nuevos clientes en el sistema y modificar sus datos. De cada cliente se recoge
su nombre y dirección.
1.2. Especificación de los requisitos no funcionales
1.2.1. Requerimientos tecnológicos
Como tecnologías a utilizar se han señalado las siguientes:
JavaServer Faces, Richfaces y Facelets para la construcción de la interfaz
web.
Hibernate para el mapeo objeto-relacional.
Spring para la integración de Hibernate y JSF.
MySQL como sistema gestor de bases de datos.
1.2.2. Seguridad
Será necesario asegurar que las personas ajenas al sistema no puedan acceder a él. Y
para aquellos usuarios que tengan privilegios de acceso, comprobar que lo hacen en
aquellas partes de la aplicación donde tienen vigencia sus permisos.
8
1.3. Modelo del dominio
Una vez analizados los requisitos especificados en los apartados anteriores, podemos
modelar una vista estática del sistema con un diagrama de clases. Se pretende dar una
visión de los conceptos que se manejan en el sistema representados mediante clases
con atributos y las relaciones definidas entre ellas.
1.3.1. Clases identificadas
Proyecto: almacena la información referente a un proyecto que se identifica por su id, denominación, tipo, plataforma, número de personas, total de horas, etc. Cada proyecto pertenece a un cliente y puede tener varios técnicos que actúan conjuntamente para su ejecución.
Factura: almacena todo lo relacionado con una factura que recoge los honorarios y
gastos producidos por un proyecto concreto y la definen su número, fecha, importe
total y el IVA.
Honorario: representa un gasto por el desarrollo de un proyecto. Como atributos
de esta clase, se almacena su importe, fecha, concepto, horas y descripción.
Cliente: esta entidad lógica representa un cliente de la empresa. De cada cliente se
recoge su denominación, dirección, identificador, código postal, país, provincia y
municipio.
Técnico: almacena todo lo relacionado con un empleado de la empresa. Cada
técnico se identifica unívocamente con su código, nombre, apellidos, usuario,
contraseña, rol (técnico o responsable) y la fecha de baja. Cada técnico puede tener
varias categorías asignadas y estar trabajando en varios proyectos a la vez.
Gasto: almacena todo lo relacionado con un gasto, su código, fecha, orden, tipo,
descripción e importe. Los gastos son registrados por un técnico e imputados a un
determinado proyecto.
Categoría: esta entidad representa una categoría con denominación y código.
TarifaCategoria: relaciona una categoría concreta con el importe que se le asigna
durante el año.
Tiempo: almacena información acerca de un registro de tiempo en la aplicación.
Un tiempo se identifica por la fecha, número de orden, descripción, número de
horas, y el tipo de trabajo realizado. Cada registro de tiempo es asignado a un
proyecto y propio de un técnico.
TipoTrabajo: almacena los distintos tipos de trabajo que se pueden realizar en un
proyecto. Se identifica por su código y denominación.
TipoGasto: esta entidad representa los distintos tipos de gastos. Se identifica por
su código y denominación.
9
TipoProyecto: hace referencia a un tipo de proyecto y se almacena su identificador
y denominación.
Plataforma: esta entidad representa una plataforma de desarrollo utilizada en la
empresa mediante su código y denominación.
1.3.2. Diagrama de clases
Figura 1: Diagrama de clases del modelo
10
2. DISEÑO
2.1. Modelo de datos
Como he comentado en el capítulo anterior, parto de una base de datos ya construida, sobre la cual se apoya la antigua aplicación web. En este apartado, voy a empezar por explicar cómo estaba esta base de datos al principio; detallaré todos sus defectos así como las medidas tomadas en el nuevo diseño para subsanarlos.
2.1.1. Antiguo modelo de datos
El antiguo modelo de datos estaba compuesto por 18 tablas sin ninguna restricción de
integridad referencial entre ellas, como se puede observar en el diagrama que se refleja
en la Figura 2. Incluso, de forma natural, se podrían deducir relaciones N:N entre algunas
de las tablas, relaciones que no estaban definidas. El Gestor de Bases de Datos utilizado
era Oracle.
2.1.1.1. Diagrama
Figura 2: Diagrama del antiguo modelo de datos
11
2.1.1.2. Entidades
En la siguiente tabla se detallan todas las entidades que forman el antiguo modelo de datos
de la empresa. De cada tabla se incluye el nombre, sus atributos y una breve descripción
de su contenido.
Tabla Atributos Descripción
CSIPROCE -- -- CSIPLADE
- Identificador - Denominación
Contiene los datos de las plataformas utilizadas por la empresa en el desarrollo de los proyectos.
CSITITRA
- Identificador - Denominación
Contiene los datos de los posibles tipos de trabajo que realizan los empleados.
CSITECNI - Identificador - Nombre
En esta tabla se almacenan los datos de los empleados de la empresa.
CSICATEG - Código - Denominación
Contiene los datos de las categorías que pueden adquirir los empleados.
CSITIPRO
- Identificador - Denominación
En esta tabla se almacenan los tipos de proyecto considerados por la empresa.
CSIESTPR -- -- CSICATEC
- Código del técnico - Año - Código de la categoría
Contiene información de las asignaciones de categorías a los empleados.
CSITARCA - Código de la categoría - Año - Importe.
Se almacena información referente a las categorías y sus tarifas.
CSITEPRO
- Código del técnico - Código del proyecto - Código de la categoría
Esta tabla relaciona un técnico con un determinado proyecto y una categoría.
CSIEMPOR -- --
CSIUSAUT
- Identificador - Contraseña - Tipo - Código del técnico
Almacena la información de acceso de los usuarios de la aplicación.
CSITIEMP
- Identificador - Fecha - Número - Código del proyecto - Descripción - Número de horas - Código del tipo de
trabajo
Almacena las actividades que realizan y registran los técnicos.
12
CSIGASTO
- Código del técnico - Fecha - Número - Tipo de gasto - Código de proyecto - Importe - Descripción
Recoge toda la información relacionada con un gasto generado durante la vida de un proyecto.
CSICONTA -- --
CSIORGAN
- Identificador - Denominación - Dirección - Código Postal - Municipio - Provincia - País
Esta tabla almacena la información de los clientes con los que interactúa la empresa.
CSIFACTU
- Identificador - Número - Código proyecto - Número de horas
facturadas - Importe de honorarios - Importe de gastos - IVA
Recoge la información de las facturas.
CSISEPRO
- Identificador - Denominación - Organismo (cliente) - Código plataforma - Código tipo proyecto - Número de empleados - Número de horas - Fecha de propuesta - Fecha de aprobación - Fecha de inicio - Fecha fin prevista - Honorarios - Gastos - Responsable del
proyecto
Almacena todo lo referente a los proyectos.
Tabla 1: Entidades del antiguo modelo
2.1.1.3. Deficiencias
El primer defecto que presenta este modelo radica en la ausencia de relaciones entre las
distintas tablas que componen el mismo.
La presencia de algunas tablas que realmente no se utilizan por la aplicación y tampoco
son necesarias para llevar a cabo otras funciones.
En la tabla de las facturas (CSIFACTU) se recoge un importe de gastos, lo que puede
suponer interpretaciones erróneas sobre su origen. Lo mismo sucede con el importe de los
honorarios.
13
En la tabla de los proyectos (CSISEPRO) se recoge el número de técnicos que participan en
el desarrollo del proyecto y el número total de horas dedicadas al mismo, atributos
innecesarios sabiendo que se pueden calcular mediante las relaciones que debe tener esta
tabla con CSITIEMP y CSITEPRO.
Siguiendo en la misma tabla y, más concretamente, con el atributo responsable del
proyecto (SPRESP), el antiguo diseño obliga a que el responsable de un proyecto sea
siempre una misma persona, el último empleado que se le asignó como responsable.
Teniendo en cuenta que un empleado puede abandonar la empresa o ser despedido de su
cargo, el antiguo diseño dejaría los datos del proyecto en una situación que no
corresponde con la realidad.
2.1.2. Modelo de datos actual
Para el nuevo modelo de datos, se han tenido en consideración todas las tablas del antiguo
modelo, exceptuando CSIPROCE, CSIESTPR, CSIEMPOR y por último CSICONTA. Dado que la
información almacenada en dichas tablas no aporta ningún tipo de beneficio al nuevo
sistema que se desea desarrollar.
2.1.2.1. Requisitos
En este apartado se recogen los requisitos que debe cumplir la nueva base de datos,
tomando como punto de partida la antigua de Oracle. Por ello, no se realiza un diseño
conceptual completo del dominio, sino que se asume el esquema lógico heredado,
ampliándolo o modificándolo según los nuevos requisitos.
Estos son los requisitos más relevantes tomados en cuenta en el proceso de diseño del
nuevo modelo:
A la empresa le interesa recoger además del nombre de sus empleados, sus
apellidos y la fecha en la que fueron dados de baja.
La empresa registra todos los tiempos dedicados por los empleados, aunque
posteriormente procede a facturarlos resumidos por técnico y actividad. Para ello,
se desea llevar un control de los honorarios facturados en un proyecto por los
trabajos realizados en el mismo.
En las facturas pueden optar por incluir varios gastos que se hayan generado
durante la realización de un proyecto.
En la antigua aplicación web, en los formularios se introducen a mano tanto el país
como la provincia y la localidad del cliente. Para ahorrar este trabajo y reducir la
probabilidad de introducir errores optan por crear tres nuevas tablas que recogen
los países, provincias y localidades.
14
2.1.2.2. Migración de Oracle a MySQL
Una vez realizados todos los cambios necesarios comentados en el apartado anterior y
establecidas las relaciones entre las distintas tablas que componen el nuevo modelo, se
migraron los datos de la antigua base de datos de Oracle a la nueva de MySQL. El proceso
de migración consistió en adaptar los datos del antiguo modelo con la ayuda de un
programa disponible en la empresa, que genera los Script para la población de la nueva
base de datos. De esta tarea se encargó Eduardo Frías Lara (mi tutor en la empresa).
2.1.2.3. Diagrama
En este diagrama se muestran todas las relaciones introducidas en el nuevo modelo, así
como las nuevas tablas y los atributos que se han añadido o eliminado en su caso.
Las tablas que se han agregado al nuevo modelo de datos, que son: CSITIGAS, CSIGAFAC,
CSIHONOR, CSILOCAL, CSIPROV, CSIPAIS y están resaltadas en color gris en la Figura 1.2 que
representa el diagrama Entidad Relación del modelo actual con todas las modificaciones
que se han introducido, mientras que las tablas que están en color azul son las que ya
existían, aunque con algunas modificaciones que se comentan en el apartado 1.2.4.
Leyenda de símbolos del diagrama:
Símbolo Significado
Indica que el atributo forma parte de una clave primaria.
Indica que el atributo forma parte de una clave alternativa (Unique).
Indica que el atributo es una clave foránea que referencia otra tabla.
Indica que el atributo forma parte de un índice de la base de datos.
Indica el sentido de una relación entre dos tablas y el atributo que referencia a la segunda tabla.
El atributo que tiene este símbolo significa que se referencia por otra(s) tabla(s).
Este símbolo sólo o combinados con otros, indica que el atributo no puede ser NULL.
Indica que la tabla que está en este extremo participa con varios en la relación.
Indica que la tabla que se encuentra en este extremo participa con uno en esta relación.
Tabla 2: Leyenda de símbolos del diagrama ER
15
Figura 3: Diagrama del modelo de datos actual
16
2.1.2.4. Diferencias respecto del antiguo modelo
Añadir la tabla CSITIGAS que almacena los distintos tipos de gasto en los que puede
incurrir la empresa durante el desarrollo de sus proyectos, y relacionarla con la tabla CSIGASTO.
Dado que una factura puede tener ninguno o varios gastos asignados. He añadido la
tabla CSIGAFAC que relaciona y agrega un gasto (CSIGASTO) a una factura (CSIFACTU).
Añadir las nuevas tablas que recogen la información de localidad (CSILOCAL), provincia (CSIPROV) y país (CSIPAIS). Con el objetivo de facilitar el proceso de introducción de datos.
Añadir la tabla CSIHONOR con los atributos código, técnico, concepto, factura, fecha, número de horas facturadas y una breve descripción de la tarea llevada a cabo. Esta tabla almacena los trabajos realizados por los empleados y facturados para un proyecto en concreto.
Eliminar los atributos número de personas y número de horas en la tabla (CSISEPRO) ya que son valores que pueden ser calculados a partir de otras tablas (CSITIEMP y CSITEPRO).
Eliminar el atributo (SPRESP) que representa a la persona responsable del proyecto. En el nuevo modelo el responsable del proyecto se asigna en la tabla (CSITEPRO) con la nueva categoría “Responsable de proyecto”.
Dado que los únicos usuarios de la aplicación serán empleados de la empresa (técnicos o responsables) se elimina la tabla (CSIUSAUT), ya que la relación que guarda con la de técnicos es uno a uno; y pasan sus atributos a formar parte de la tabla (CSITECNI). De esta forma cualquier empleado dispondrá de una clave y un nombre de usuario para acceder a la aplicación.
Almacenar las claves de los técnicos encriptadas en la base de datos usando el algoritmo SHA-1.
Para evitar eliminar los datos de los técnicos y así perder información relacionada con los mismos, y también mantener un control de los que están activos o no, he añadido la fecha de baja en la tabla (CSITECNI) que indica si un técnico está dado de baja o no.
En la tabla (CSIFACTU) se eliminan los atributos “honorarios” y “gastos”, reemplazándolos con relaciones con las tablas (CSIHONOR) y (CSIGAFAC). Por otro lado, se añade un atributo “Total” que recoge el importe total de la factura.
Podemos observar que en todas las tablas se introdujo un identificador “código” como clave primaria, aunque en algunas no hace falta. Todo ello fue para adaptar el nuevo modelo al uso que se hará de él, más concretamente en el Mapeo Objeto Relacional (ORM) en el que se usará Hibernate.
Este último gestiona las claves primarias compuestas como una clase aparte, algo que puede dificultar nuestro problema aún más. Por ello, he tomado la decisión de crear identificadores autoincrementales y gestionar las operaciones que se realizan sobre la base de datos con la ayuda de las claves candidatas.
17
2.2. Arquitectura software
La aplicación utiliza una arquitectura cliente/servidor de n-capas, lo que significa que se modela como un servicio que es proporcionado por un servidor y un conjunto de clientes que usan dicho servicio. La arquitectura n-capas, en este caso de tres capas, significa que cada capa se construye en términos de los que tiene por debajo y proporciona una base de implementación para aquellas que tiene por encima. Spring Framework proporciona una implementación del patrón Modelo Vista Controlador. Este patrón separa los datos de una aplicación de la interfaz de usuario y de la lógica de negocio, lo que reduce el impacto sobre el resto de componentes en caso de introducir cambios. En este caso, los componentes del patrón MVC serán: - Modelo: estará formado por los Java Beans de JSF.
- Vista: las vistas JSF en formato XHTML para mostrar las interfaces de usuario.
- Controlador: las clases Controller de Spring que se encargan de recoger los datos introducidos por el usuario y pasarlos a la capa de lógica de negocio y posteriormente redireccionar los resultados obtenidos hacia otras páginas JSF.
2.2.1. Capa de presentación
Esta capa proporciona una interfaz visual con la que interactúan los usuarios de la aplicación. Se encarga de mostrar los datos, recoger las entradas de usuario, validarlas y delegar su procesamiento en la capa de lógica de negocio. Esta capa está formada por las paginas JSF que se corresponden con la Vista del patrón Modelo Vista Controlador (MVC) y las clases Controller de Spring, que como su nombre indica, juegan el papel del Controlador en MVC. Las tecnologías elegidas para esta capa son JavaServer Faces y Richfaces para los componentes de la interfaz, Facelets para construir árboles de componentes y por último Spring Framework en los controladores.
2.2.2. Capa de lógica de negocio
Esta capa hace de puente entre la capa de persistencia y los controladores Spring. Sus objetos no sólo tienen datos, también la lógica asociada a esos objetos específicos. La tecnología utilizada, al igual que en la capa de presentación, es Spring Framework para denotar todas las clases de esta capa como servicios de aplicación con la anotación “@Service”. Las clases de esta capa forman parte del componente Modelo del patrón MVC.
18
2.2.3. Capa de persistencia
La capa de acceso a datos se encarga de realizar las cuatro operaciones básicas sobre una base de datos: inserción, modificación, consulta y borrado. Para ello, usaré Spring Framework basado en Hibernate. Las clases de esta capa junto con la anterior forman parte del componente Modelo del patrón MVC. En esta capa emplearemos el patrón DAO (Data Access Object) para abstraer y encapsular los accesos a la base de datos y manejar la conexión con la fuente para obtener o almacenar datos. El DAO implementa el mecanismo de acceso requerido para trabajar con la base de datos, aunque oculta los detalles de implementación a sus clientes.
Figura 4: Diagrama de algunas clases de persistencia
Normalmente en esta capa se implementan las cuatro operaciones básicas (CRUD) para cada una de las clases, lo que hace que el código escrito para una se repita tantas veces como clases tenga esta capa. Para evitar que esto ocurra voy a trabajar con un DAO genérico y abstracto, de manera que cada clase que extiende este DAO no tendrá la obligación de volver a reescribir el código de estas operaciones. Todas las clases de esta capa se denotan por la anotación @Repository de Spring. De esta manera cada DAO accede a las operaciones básicas definidas en el DAO genérico, como se observa en la siguiente figura; pudiendo implementar otras específicas.
Los DAOs se declaran con Scope Singleton que asegura que sólo exista una instancia de
este bean por el contenedor de Spring. Este último crea una instancia única de todos los
DAOs y cada vez que recibe una llamada para obtener ese bean, responde con la misma
instancia.
19
Figura 5: Comunicación entre DAOs
2.2.4. Comunicación entre las capas
Para ver cómo sería la comunicación entre las distintas capas de la aplicación, vamos a ceñirnos a una funcionalidad concreta, que en este caso sería añadir un nuevo proyecto. En primer lugar se envía una solicitud para añadir un nuevo proyecto, una vez que se validen todos los datos del proyecto introducidos por el usuario; el controlador (Controlador de Proyectos) recibe dicha solicitud y actúa en consecuencia usando los servicios de la lógica de negocio (Servicio de Proyectos) que a su vez añade toda la lógica necesaria al objeto, realiza las comprobaciones que proceden y delega el resto de la tarea en la capa de persistencia (DAO de Proyectos) para que se encargue de su almacenamiento en la base de datos. El DAO de proyectos inserta el proyecto o lanza la excepción oportuna a la capa inmediatamente superior que a su vez comunica sus resultados al controlador. Este último realiza una consulta en el fichero de configuración para redireccionar la solicitud a la vista adecuada.
20
Figura 6: Flujo de “añadir nuevo proyecto”
2.3. Interfaces de usuario
Las interfaces de usuario son el elemento principal para la comunicación entre los usuarios y aplicación. En el desarrollo de esta aplicación, el diseño de la interfaz no fue uno de los principales puntos de atención ya que muchos de los componentes de la interfaz vienen determinados por Richfaces. En las siguientes figuras se mostrarán las decisiones tomadas para el diseño de las interfaces de usuario.
2.3.1. Interfaz de login
En esta primera pantalla se recogen los datos necesarios de autenticación;
usuario y contraseña del usuario.
21
Figura 7: Prototipo de la interfaz de login
2.3.2. Partes fijas de la interfaz
Exceptuando la primera página de login, todas las demás páginas a las que puede
acceder el usuario estarán compuestas por cuatro elementos fijos: menú, cabecera,
cuerpo y pie de página como se puede observar en la Figura 1.6.
El menú: en esta parte de la página se mostrarán las distintas opciones a las
que puede acceder el usuario. Si se trata de un usuario responsable; las opciones el menú serán más diversas que en el caso de un técnico.
Cabecera: compuesta por el título de la página, el nombre del usuario en sesión y otras opciones como cambiar su clave y salir de la aplicación.
Imagen: con el logotipo de la empresa Suma Info S.L.
Pie de página.
Figura 8: Prototipo del esqueleto general
22
2.3.3. Interfaz de páginas con listado
En todas las opciones que puede elegir el usuario, la primera página que se
muestra es un listado de todos los elementos donde puede consultar la
información básica, crear nuevo, editar o eliminar algún elemento del listado.
Figura 9: Prototipo de páginas con listado
2.3.4. Interfaz de páginas con formulario
En las páginas donde se espera recibir datos nuevos o modificarlos se muestra un
formulario con los componentes necesarios en cada caso para la recogida de los
datos introducidos por los usuarios.
Figura 10: Prototipo de páginas con formulario
23
3. IMPLEMENTACIÓN
3.1. Tecnologías empleadas
3.1.1. Maven
Utilizado para crear la estructura de directorios del proyecto. También se encarga de descargar las dependencias que se indican en el fichero pom.xml (librerías usadas en el proyecto) así como las dependencias de estas últimas.
Maven utiliza una matriz de repositorios remotos que le permite localizar y descargar todo lo necesario para generar el proyecto. Además de estos repositorios remotos también existe uno local que utiliza Maven como caché evitando la descarga en las siguientes generaciones del proyecto y así reducir el tiempo que supondría volver a descargarse todas las librerías de Internet.
En la siguiente imagen se pueden intuir gráficamente todas las dependencias del proyecto “csi_sumainfo”, algunas son directas y otras indirectas.
Figura 11: Dependencias del proyecto
24
3.1.2. Hibernate
Es el Framework para el mapeo Objeto Relacional. Para llevar a cabo este proceso he utilizado anotaciones en las entidades, con ello, voy a conseguir convertir los tipos de Java a los definidos en la base de datos MySQL y viceversa, sin preocuparme de cómo lo gestiona Hibernate internamente. Una de las ventajas que ofrece esta tecnología es su lenguaje de consultas HQL (Hibernate Query Lenguage) el cual es más orientado a objetos.
Spring Framework nos provee de una clase plantilla llamada HibernateTemplate que nos asegura que las sesiones sean abiertas y cerradas automáticamente y hace que nuestras llamadas participen en transacciones.
En mis DAOs voy a tener acceso directo a esta clase mediante el método que heredan al extender de la clase abstracta HibernateDaoSupport.
Para la integración de Spring con Hibernate hay que definir el Session Factory de Hibernate para el manejo de sesiones. En esta configuración utilizaremos una clase que contiene Spring en su módulo ORM para la integración con Hibernate:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configurationClass"
value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="configLocation">
<value>classpath:${hibernate.cfg.file}</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.sumainfo</value>
</list>
</property>
</bean>
HQL (Hibernate Query Lenguage):
Es un lenguaje propio de Hibernate, como su nombre indica. Es muy parecido a SQL, sin
embargo, HQL es completamente orientado a objetos y comprende nociones como
herencia, polimorfismo y asociación. Es sensible a las mayúsculas y minúsculas.
Ejemplo de consulta con HQL:
String consulta = "SELECT c FROM Factura c WHERE c.proyecto.organismo.codigo = ?";
Como podemos ver, la consulta se realiza sobre el objeto “Factura” y no se realiza sobre la
tabla “CSIFACTU”. Su manera peculiar de acceder a los atributos de la clase que no son
atributos de una tabla. Cabe mencionar también que HQL permite realizar consultas
parametrizadas.
En este proyecto, y aunque Hibernate ofrece la posibilidad de trabajar con SQL como
lengua de consultas, he optado por utilizar HQL debido a las múltiples ventajas que ofrece
frente al primero.
25
3.1.3. Richfaces
Utilizado en la construcción de las vistas junto con los componentes JSF. Richfaces permite definir por medio de etiquetas de JSF diferentes partes de una página que se desea actualizar con una solicitud AJAX y sincronizar automáticamente con el árbol de componentes JSF sin tener que recargar toda la página Web. Proporcionando así varias opciones para enviar peticiones AJAX al servidor.
Re-Rendering:
Un atributo clave de Richfaces es “reRender” que permite indicar una zona en la página que debería ser actualizada como respuesta a la interacción AJAX. El valor de este atributo debe ser un identificador de un componente JSF o una lista de identificadores.
En el ejemplo siguiente se indica que los componentes JSF nueva,tablaCategorias,nuevaTarifa son re-renderizables, incluyéndose a continuación, como ejemplo, el componente tablaCategorias:
<a4j:commandButton value="Guardar" styleClass="boton"
action="#{controladorCategorias.insertarCategoria}"
reRender="nueva,tablaCategorias,nuevaTarifa" />
… …
<rich:extendedDataTable selectionMode="single" id="tablaCategorias" >
Richfaces también permite organizar el flujo de una página dentro del componente
<a4j:include>. Gracias a este componente podemos sustituir el contenido de una página
por otro. El contenido se toma de la vista obtenida de la regla de navegación definida en el
fichero de configuración faces-config.xml.
En la página de clientes se incluye en primer lugar el listado de los clientes definido en la
vista listado.xhtml. Si el usuario accede a la opción de crear o modificar un cliente, se
añade automáticamente el código de la vista que procede en cada caso, reemplazando de
esta manera el listado anterior.
<a4j:include viewId="/pages/clientes/listado.xhtml" ajaxRendered="true"/>
3.1.4. Facelets
Es un Framework para plantillas centrado en la tecnología JSF, por lo que se integran de manera muy fácil. Con el uso de Facelets podemos definir vistas para reutilizar varias veces sin necesidad de volver a copiar el código. También permite el paso de parámetros entre distintas vitas.
Mediante su componente <ui:composition> podemos envolver un conjunto de componentes (JSF y Richfaces) para definir el contenido de una parte de la vista que posteriormente se podrá incluir en otras páginas en el componente <ui:include>, como pueden ser el pie de la página, la cabecera y el menú entre otros.
26
Por ejemplo, la definición del pie de página utilizado en el desarrollo de las vistas JSF, definido en el fichero “footer.xhtml”:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<rich:spacer width="50%" />
<h:outputText value="© 2013 - Suma Info S.L." style="font-size:
12px;color: #620f0f"/>
</ui:composition>
Esto hace posible la reutilización de este fragmento de código en varias páginas como
sigue:
<f:facet name="footer">
<ui:include src="/pages/includes/footer.xhtml" />
</f:facet>
3.1.5. Spring
Está basado en un conjunto de módulos que proporcionan todo lo necesario para desarrollar una aplicación empresarial. Su componente principal consiste en un contendor de Beans que permite, mediante Inversión de Control (IoC), gestionar las instancias así como su creación y destrucción. Los componentes sólo se encargan de declarar las dependencias que necesitan y el contenedor se encarga de inicializar los componentes necesarios antes de inyectar su referencia a quien la necesite.
La directiva @Autowired utilizada en el proyecto, inyecta las dependencias en Spring buscando dentro del contexto un bean cuya clase coincide con el tipo de la variable. Para el mismo propósito tenemos también a @Inject y @Resource.
Ejemplo de uso de la anotación @Resource en el controlador de acceso para cargar el AuthenticationManager declarado en el fichero de spring-security.xml:
@Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager;
Ventajas que aporta Spring:
- Manejo de transacciones. - Integración con Hibernate. - Seguridad declarativa mediante anotaciones.
3.1.6. Informes con Jasperreports
Es una tecnología “opensource” que he utilizado en este proyecto para generar los informes de facturas. Permite generar informes en múltiples formatos; CVS, XML, TXT, HTML, XLS y otros más.
27
En Jasperreports los informes se definen en un fichero XML, el cual será compilado por las librerías Jasperreports y generará un fichero con la extensión “.jasper” que se utiliza para rellenar y mostrar los informes finales.
En este caso utilicé Ireport para generar las plantillas de los informes y compilarlos antes de ser usados por la aplicación. En estas plantillas se definen los datos, dónde y cómo se van a incluir. Estos datos se obtienen mediante una conexión a la base de datos.
Figura 12: Plantilla “jrxml” de facturas
En esta aplicación, la clase InformesService es la que se encarga de generar los informes con su método “generaInforme”. El código de este método se puede resumir de la siguiente manera:
1) Prepara el canal de salida: En el siguiente código obtengo el canal de salida para enviar la respuesta al usuario, añadiéndole todas las cabeceras necesarias:
HttpServletResponse response = (HttpServletResponse)
faces.getExternalContext().getResponse();
out = response.getOutputStream();
response.setContentType("application/pdf");
String nombreFichero = "Informe_facturas";
response.setHeader("Content-Disposition", "attachment; filename=\"" +
nombreFichero + ".pdf\"");
2) Genera el informe: En esta parte, genero el informe tomando como base el archivo (plantilla compilada) “reporte.jasper”, los parámetros, que en este caso no hay ninguno y la conexión JDBC para obtener los datos.
if (params == null) {
params = new HashMap<String, Object>();
}
reportStream = faces.getExternalContext().getResourceAsStream(DIRECTORIO_FACTURAS
+ "reporte.jasper");
JasperPrint print = JasperFillManager.fillReport(reportStream, params,
connection);
28
3) Exporta el informe al canal de salida: Una vez generado el informe, lo exporto con la clase JRExporter de la librería Jasperreports en formato PDF, en este caso. Así mismo, le paso como parámetros el nombre que le voy a dar al fichero, el canal de salida (out) y el informe generado en el punto anterior (print).
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,
nombreFichero+".pdf");
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
exporter.exportReport();
3.2. Validación y conversión
El ciclo de vida de una petición JavaServer Faces es similar al de una página JSP; el cliente realiza una petición de la página y el servidor responde con la página traducida a HTML. Sin embargo, y debido a las características extras que ofrece la tecnología JSF, este ciclo de vida proporciona algunos servicios adicionales mediante la ejecución de algunos pasos extras.
Para entender mejor el ciclo de vida de una página JSF, quizá nos sirva de ayuda el siguiente diagrama, donde se reflejan los pasos desde que se pide una página hasta que se recibe una respuesta:
Figura 13: Ciclo de vida JSF
Uno de los puntos débiles de la antigua aplicación de control de proyectos de la empresa se encontraba en la conversión y validación de los datos introducidos por los usuarios. En algunos casos, permitía incluso la inserción de cadenas vacías cuando se requería un valor.
JSF nos proporciona dos mecanismos que nos ayudan a validar los valores que introduce el usuario a la hora de enviar los formularios.
29
El primer mecanismo es el de conversión (segunda fase en el ciclo de vida JSF) y está definido por el interfaz javax.faces.convert.Converter y sus implementaciones. Las conversiones nos aseguran que el tipo de un dato introducido en un formulario JSF sea el correcto o el esperado por la aplicación. JSF invoca a los conversores (de por defecto o los creados por el usuario) antes de efectuar las validaciones. En caso de que un tipo introducido no se corresponda con el tipo Java apropiado, el conversor lanzará una excepción de conversión.
La librería Core de JSF incluye elementos básicos para la generación de una vista y también incluye otros especiales conocidos como validadores y conversores que permiten realizar validaciones y conversiones de datos.
Algunas de los conversores que se han utilizado en la implementación de la capa de presentación son:
1) NumberConverter: en la conversión de números, porcentajes y monedas. Monedas: <f:convertNumber type="currency" locale="es_ES" /> Números: <f:convertNumber />
2) DataTimeConverter: para convertir y mostrar las fechas en el formato deseado. Ejemplo: <f:convertDateTime pattern="dd/MM/yyyy" />
El segundo mecanismo es el de validación y se encuentra en la tercera fase del ciclo de vida JSF. Está definida por el interfaz javax.faces.validor.Validator y sus implementaciones. En esta fase, JSF examina los atributos del componente que especifican las reglas de validación y compara esas reglas con el valor local almacenado en el componente. Si el valor no es válido JSF añade un mensaje de error al FacesContext y avanza el ciclo de vida a la fase de renderizar la respuesta para que la página sea dibujada de nuevo incluyendo los mensajes de error.
En este proyecto, he realizado las validaciones usando los componentes de la librería Core de JSF en combinación con Hibernate y el componenete ajaxValidator de Richfaces, que permite validar datos en el lado del cliente.
Ejemplo:
<h:inputTextarea id="descripcion" rows="7"
value="#{controladorTiempos.tiempo.descripcion}" required="true"
requiredMessage="La descripción es requerida.">
<rich:ajaxValidator event="onblur" />
</h:inputTextarea>
30
3.3. Seguridad
Uno de los aspectos más importantes que se han tenido en cuenta a la hora de desarrollar esta aplicación fue la seguridad. Entendiendo como tal la necesidad de saber que el usuario es quien dice ser (autenticación), y permitirle acceso sólo a aquellos recursos necesarios (autorización). Spring Security proporciona la funcionalidad necesaria para adaptar los mecanismos de seguridad en aplicaciones Java utilizando características de programación orientada a aspectos.
3.3.1. Autenticación
Consiste en determinar quién desea hacer uso del sistema y comprobar que es quien dice ser. En Spring Security el AuthenticationManager es el encargado de validar la combinación nombre de usuario y contraseña, devolviendo los roles asociados a dicho usuario. La configuración del AuthenticationManager se realiza en el fichero de configuración de spring-security.xml. El elemento <authentication-manager> registra un gestor de autenticación. En concreto registra una instancia de ProviderManager, un gestor de autenticación que delega su responsabilidad en uno o más proveedores de autenticación. Spring Security incluye la posibilidad de obtener los usuarios y permisos utilizando ficheros XML, bases de datos JDBC, LDAP o simplemente declararlos en el fichero de configuración (spring-security.xml). En esta aplicación y para evitar que Spring acceda directamente al contenido de la base de datos, he configurado un servicio mediante la implementación del interfaz UserDetailsService. Este interfaz describe un objeto que realiza el acceso a los datos con un único método loadUserByUsername y devuelve un objeto de tipo UserDetails construido a partir de los datos obtenidos, en caso contrario lanza una excepción de tipo UsernameNotFoundException. He aquí el código del método:
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException, DataAccessException {
UserDetails user = null;
try {
Tecnico tecnico = tecnicoDAO.tecnicoByUser(username);
if (tecnico == null) {
throw new UsernameNotFoundException(username + " no encontrado");
}else{
// Se construye un nuevo usuario con los datos del técnico obtenido
user = new User(tecnico.getUsuario(), tecnico.getClave(),
tecnico.isEnabled(),
tecnico.isAccountNonExpired(), tecnico.isCredentialsNonExpired(),
tecnico.isAccountNonLocked(), tecnico.getAuthorities()
);
}
} catch (PersistenciaException ex) {
Logger.getLogger(DetallesUsuarioService.class.getName()).log(Level.SEVERE,
null, ex);
}
return user; }
31
Y en el fichero de configuración spring-security.xml:
Declaración del servicio de autenticación:
<beans:bean id="detallesUsuarioService"
class="com.sumainfo.servicios.DetallesUsuarioService" />
Declaración del PasswordEncoder:
<beans:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.MessageDigestPassw
ordEncoder">
<beans:constructor-arg value="SHA-1"/>
</beans:bean>
Declaración del AutheticationManager:
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="detallesUsuarioService">
<password-encoder ref="passwordEncoder"/>
</authentication-provider>
</authentication-manager>
Al proveedor de autenticación se le especifica un PasswordEncoder con el algoritmo de encriptación SHA-1, que utiliza para realizar la comprobación de las contraseñas, ya que éstas se guardan encriptadas en la base de datos. El proceso de autenticación en esta aplicación se define como sigue: El usuario introduce sus datos en el formulario de la página de login (entrada.xhtml) y pulsa el botón acceder. Esta petición la procesa el Controlador de acceso de la aplicación, que define un método de login. En este método se construye un UsernamePasswordAuthenticationToken con las credenciales del usuario (clave y nombre de usuario), que se le pasan al AuthenticationManager de la aplicación para su autenticación. El AuthenticationManager se declara como una dependencia del Controlador de acceso, es decir, Spring buscará dentro del contexto una variable con el nombre "authenticationManager” y encontrará el declarado con el mismo alias en el fichero de configuración spring-security.xml.
@Resource(name = "authenticationManager")
private AuthenticationManager authenticationManager;
Las decisiones tomadas por el AuthenticationManager en esta aplicación para permitir el acceso al usuario, entre otras cosas, se basan en el campo de fecha de baja del usuario. De tal modo que un usuario que haya sido dado de baja con anterioridad al proceso de autenticación, su acceso será rechazado por la aplicación.
32
Si el proceso de autenticación es exitoso, se construye un objeto de tipo Authentication con los datos del usuario y se pone en el contexto de Spring Security:
SecurityContextHolder.getContext().setAuthentication(authenticate);
En la página entrada.xhtml de login, interesa que la solicitud se haga bajo el protocolo http seguro ya que en ese formulario viaja la contraseña del usuario. Para ello, forzamos el uso de https en la configuración de Spring Security:
<intercept-url pattern="/pages/entrada.xhtml" access="permitAll" requires-
channel="https"/>
De esta forma, cada vez que se produce una solicitud con formato “/pages/entrada.xhtml”,
Spring Security va a detectar que se requiere el uso del canal https y va a redirigir la
solicitud de forma automática a través de https.
Figura 14: Proceso de autenticación en Spring Security
33
3.3.2. Autorización
Una vez finalizado el proceso de autenticación del usuario, entra en juego la parte del
sistema encargada de la autorización, con el fin de permitir que éste acceda sólo a aquellos
recursos a los que tiene permiso. Para ello Spring Security intercepta todas las peticiones
http utilizando filtros y actúa en consecuencia.
El acceso a un recurso no permitido puede acabar lanzando una excepción de tipo
AccessDeniedException.
Para dejar el acceso a los recursos bien delimitado para cada rol de esta aplicación, he
configurado en el fichero spring-security.xml los siguientes permisos:
1) PermitAll: para aquellos recursos a los que tienen acceso todos los usuarios
(autenticados o no), por ejemplo la página de login:
<intercept-url pattern="/pages/entrada.xhtml" access="permitAll" />
2) isAuthenticated(): para recursos a los que pueden acceder usuarios autenticados
por la aplicación, por ejemplo la carpeta de los informes:
<intercept-url pattern="/WEB-INF/informes/**" access="isAuthenticated()"/>
3) hasRole(el_rol): para aquellos usuario con el rol definido por la cadena “el_rol”.
Ejemplo, el contenido de la carpeta de facturas:
<intercept-url pattern="/pages/facturas/**" access="hasRole('R')"/>
4) hasAnyRole(lista_de_roles): son recursos a los que pueden acceder todos los
usuarios con alguno de los roles contenidos en la lista “lista_de_roles”. Ejemplo, el
contenido de la carpeta de tiempos:
<intercept-url pattern="/pages/tiempos/**" access="hasAnyRole('R','T')"/>
En caso de que se produzca una excepción AccessDeniedException el usuario será
redireccionado a la página principal.
<http auto-config="true" use-expressions="true" access-denied-page="/pages/index.xhtml">
34
3.4. El proceso de trabajo
En la figura 15 vemos las fases por las que pasa una petición para ser procesada por la
aplicación, donde se encuentran las validaciones de los datos en primera lugar. Una vez
superadas estas últimas, actúa el controlador pertinente que pasa los datos a un servicio
de la capa de lógica de negocio para realizar las comprobaciones y añadir la lógica
necesaria a los objetos antes de llamar al DAO o conjunto de DAOs, para ejecutar las
sentencias contra la base de datos.
Figura 15: Proceso de trabajo en la aplicación
Para ver más en detalle este proceso de trabajo, y siguiendo con la funcionalidad de
“añadir un nuevo proyecto” explicada en el capítulo de diseño, veamos los pasos seguidos
desde que empieza el proceso, cuando el usuario introduce los datos del proyecto, hasta
que finaliza almacenándolo en la base de datos.
3.4.1. La vista JSF
En la vista JSF con formato XHTML se encuentran todos los componentes necesarios para
la recogida de los datos del proyecto así como su validación y conversión. Por una parte
están los datos obligatorios y por otra los opcionales:
1) Datos obligatorios: la denominación, plataforma de desarrollo, cliente, el tipo de
proyecto y la fecha de propuesta del mismo. Todos estos elementos se denotan por
el atributo “required” a true, para indicar que son obligatorios. También, se
personaliza un mensaje de error con el atributo “requiredMessage” con el mensaje
pertinente a cada caso. Como ejemplo, tomamos el TextArea para introducir la
denominación del proyecto.
El atributo “required” exige que ese campo sea distinto de NULL, pero no detecta
las cadenas vacías. Para ello, he empleado una de las restricciones de Hibernate
Validator “NotBlank” que realiza un trim a la cadena antes de su comprobación.
35
<h:inputTextarea id="denominacion" rows="5"
value="#{controladorProyectos.proyecto.denominacion}" title="Denominacion"
required="true" requiredMessage="La Denominacion es requerida."
styleClass="inputText">
<rich:ajaxValidator event="onblur" />
</h:inputTextarea>
El componente <rich:ajaxValidator> se encarga de realizar las validaciones vía
AJAX.
2) Datos opcionales: fecha de aprobación, fecha de fin prevista y la fecha de inicio
del proyecto.
<a4j:outputPanel id="calendar1" layout="block">
<rich:calendar value="#{controladorProyectos.proyecto.faprobacion}"
id="faprobacion" inputStyle="height: 20px" inputClass="inputText"
datePattern="dd/MM/yyyy" cellWidth="24px" cellHeight="22px"
style="width:200px" inputSize="40">
<rich:ajaxValidator event="onchanged" />
</rich:calendar>
</a4j:outputPanel>
En esta vista se sitúa el componente <rich:messages> para mostrar los mensajes de error
que se producen durante el proceso de validación de los datos o los que devuelve el
controlador en caso de que se produzca un error.
<rich:messages layout="table" tooltip="true" title="Mensaje de error"
showDetail="false" showSummary="true" style="color: red">
<f:facet name="errorMarker">
<h:graphicImage value="/img/error.png" width="15px" height="15px"/>
</f:facet>
</rich:messages>
Una vez completado el formulario con todos los datos necesarios del proyecto, se envía la
solicitud de inserción al Controlador de proyectos al pulsar el botón “Guardar”, como se
observa en el atributo action del componente <a4j:commandButton>.
<a4j:commandButton styleClass="boton" value="Guardar"
action="#{controladorProyectos.insertarProyecto}" />
3.4.2. El Controlador
Se encarga de realizar todas las operaciones sobre proyectos, comunicando las vistas JSF
con los servicios de la capa de lógica de negocio.
Todos los controladores de la aplicación son denotados por la directiva @Controller, que le
indica a Spring que ésta clase sirve para manejar las peticiones y respuestas recibidas y
enviadas a los usuarios.
En el Controlador de proyectos, en su método “insertarProyecto”, se encuentra el siguiente
código:
36
@Autowired
private ProyectoService proyectoService;
…… …
…… …
public String insertarProyecto() {
String accion = "";
try {
this.proyecto = aniadirDatosProyecto(proyecto);
proyecto.setFinalizado(false);
if (proyectoService.saveProyecto(proyecto)) {
proyecto = new Proyecto();
recuperaProyectos();
construyeListaProyectos();
construyelistaProyectosActivos();
accion = "proyectos";
} else {
FacesContext.getCurrentInstance().addMessage(null, new
FacesMessage("Este proyecto ya existe"));
}
} catch (PersistenciaException ex) {
Logger.getLogger(ControladorProyectos.class.getName()).log(Level.SEVERE, null,
ex);
FacesContext.getCurrentInstance().addMessage(null, new
FacesMessage("Error al intentar guardar el proyecto"));
}
return accion;
}
Peculiaridades del método:
1) Devuelve un “String” que contiene el nombre de la siguiente vista a la cual se
redirige la respuesta una vez que termina bien el proceso de inserción. El nombre
de la vista se determina en el fichero faces-config.xml como sigue:
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>proyectos</from-outcome>
<to-view-id>/pages/proyectos.xhtml</to-view-id>
<redirect/>
</navigation-case>
… …
… …
</navigation-rule>
El elemento <from-autocome> indica la cadena de acción, y <to-view-id> el path de
la vista asociada. <redirect/> indica que se realiza una redirección a la página. En
caso de no indicar nada, el paso a la vista se haría con un forward.
2) Manejo de errores y envío de mensajes de información a la vista mediante
FacesContext.getCurrentInstance().addMessage() que se muestran en el componente
<rich:messages> de la vista JSF antes explicado.
3) Una vez guardado el proyecto, vuelve a actualizar las listas de proyectos para
refrescar el contenido de las tablas que las usan en la vista JSF.
37
4) No recibe ningún parámetro, ya que el objeto “proyecto” es propio de la clase y
obtiene los valores de sus atributos directamente de la vista JSF. Ya que en ésta se
hace referencia a este objeto y sus atributos. Por ejemplo, el campo denominación
del proyecto tiene el siguiente valor:
<h:inputTextarea id="denominacion" rows="5"
value="#{controladorProyectos.proyecto.denominacion}" ………
5) Tiene un atributo de tipo “ProyectoService”, inyectado con la anotación
@Autowired de Spring, en el que delega la función de guardar el proyecto. En caso
de que se guarde el proyecto, la página será redirigida al listado de proyectos y en
caso contrario, lanzará un error al usuario para informarle.
3.4.3. El Servicio
El servicio de proyectos y en su método “saveProyecto” se encarga de:
1) Generar un número de proyecto para el atributo “idProyecto” con la información
necesaria.
2) Comprobar que el proyecto no existe en la base de datos mediante una llamada al
DAO específico de proyectos con el método find(). Este método busca y encuentra
un proyecto por su clave candidata (denominación y cliente). Y por último llama al
DAO que se encarga del mapeo Objeto Relacional de los proyectos.
3.4.4. El DAO
Como se trata de una operación básica, el DAO genérico será el encargado de realizarla:
public Integer save(T objecto) throws PersistenciaException {
Integer id = null;
try {
id = (Integer) getHibernateTemplate().save(objecto);
getHibernateTemplate().flush();
} catch (DataIntegrityViolationException ex) {
this.logger.error(ex);
throw new PersistenciaException(PersistenciaExceptionCode.INSERT_FAILED,
ex);
} catch (DataAccessException ex) {
this.logger.error(ex);
throw new PersistenciaException(PersistenciaExceptionCode.INSERT_FAILED,
ex);
} catch (Exception ex) {
this.logger.fatal(ex);
throw new PersistenciaException(PersistenciaExceptionCode.INSERT_FAILED,
ex);
}
return id;
}
38
Peculiaridades del método:
1) Accede a la clase plantilla HibernateTemplate mediante su método
getHibernateTemplate(). Una de las responsabilidades de esta plantilla es gestionar
las sesiones, lo que implica su apertura y cierre, así como garantizar que exista
sólo una sesión por cada transacción. Ofrece además algunos métodos como save,
find, update, delete, getSession y muchos más.
2) Envuelve las excepciones (DataIntegrityViolationException, Exception y
DataAccessException) en una propia de la capa de persistencia
(PersistenciaException).
3) El método hibernateTemplate.flush() que a su vez ejecuta una llamada a
Session.flush() para confirmar los cambios realizados.
3.5. Pruebas
Para realizar las pruebas unitarias he utilizado Spring TestContext Framework que
proporciona un soporte de integración con JUnit4 a través de un Runner a medida. En este
proyecto la integración la realicé a través de SpringJUnit4ClassRunner, que posibilita la
realización de pruebas unitarias o de integración, la carga del contenedor de Spring y la
inyección de dependencias en las clases de test.
He aquí la configuración de la clase que realiza las pruebas sobre el DAO de clientes:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring-config.xml"})
La anotación @RunWith sirve para que la ejecución de la clase de prueba unitaria la
efectúe la clase especificada como parámetro, en este caso SpringJUnit4ClassRunner y no
la clase Runner de JUnit. Esta clase se encarga de levantar el contexto de Spring y resolver
todas las dependencias requeridas por la clase de prueba.
Para obtener el contexto Spring utiliza la información especificada en
@ContextConfiguration, donde se encuentra la localización del fichero(s) de
configuración de Spring.
Una de las pruebas más significativas que dio lugar a la toma de nuevas decisiones en la
implementación de la capa de persistencia, fue la siguiente:
Al principio el código de los métodos find() de la clase ClienteDAO no se beneficiaba de las
operaciones que ofrece la plantilla HibernateTemplate, sino que creaba una nueva Query a
partir de la sesión en curso de Hibernate como se observa en el siguiente código:
39
public Cliente find(Cliente cliente) throws PersistenciaException {
Cliente clienteBD = null;
try {
String hql = "SELECT c FROM Cliente c WHERE c.denominacion = :denominacion
and c.direccion= :direccion";
Query query =
getHibernateTemplate().getSessionFactory().getCurrentSession().createQuery(hql
);
query.setParameter("denominacion", cliente.getDenominacion());
query.setParameter("direccion", cliente.getDireccion());
clienteBD = (Cliente) query.uniqueResult();
………
………
Al realizar la prueba de este método me di cuenta de que no me devolvía los resultados
esperados, todo ello por causa de la obtención de la sesión a partir del método
getHibernateTemplate().getSessionFactory().getCurrentSession. Debido a la gestión que realiza
Spring de las sesiones no encontraba ninguna sesión para utilizar.
Todo ello, me llevó a pensar en una nueva solución que fue añadir un nuevo método en el
DAO genérico para que pueda ser utilizado por todos los DAOs que realicen consultas
personalizadas. Este método es findByQuery que recibe una consulta HQL y una lista de
parámetros para llamar a HibernateTemplate, aprovechando de esta manera el método
find que ofrece esta clase plantilla.
protected List<T> findByQuery(String queryString, Object[] values) throws
PersistenciaException {
List<T> lista = null;
try {
lista = getHibernateTemplate().find(queryString, values);
………
………
return lista;
}
Y así hacer uso de este método en el resto de los DAOs como sigue:
public Cliente find(Cliente cliente) throws PersistenciaException {
Cliente clienteBD = null;
try {
String hql = "SELECT c FROM Cliente c WHERE c.denominacion = ? and
c.direccion= ?";
List<Cliente> lista = super.findByQuery(hql, new String[]
{cliente.getDenominacion(), cliente.getDireccion()});
if (!lista.isEmpty()){
clienteBD = lista.get(0);
}
…… ……
…… ……
…… ……
40
4. GESTIÓN DEL PROYECTO
4.1. Planificación inicial
La planificación de este proyecto la realicé a finales de enero de 2013 para ir revisando y
modificando su contenido a lo largo del proyecto. De ésta manera poder comprobar que lo
planificado al principio se cumple a tiempo y que no haya ningún desfase significativo que
pueda afectar de manera negativa al desarrollo del proyecto.
4.2. Definición de tareas
Una de las tareas principales de la planificación de un proyecto es la definición de las
tareas que lo componen. En la siguiente figura se describen de forma más detallada todas
las tareas derivadas de este Trabajo Fin de Grado.
Figura 16: Descomposición de tareas
4.3. Diagrama de Gantt
En el siguiente diagrama Gantt se recogen todas las tareas realizadas en este proyecto así
como la duración planificada de cada una y los hitos más importantes que se han tenido en
cuenta.
Trabajo Fin de Grado
Gestión del proyecto
Planificación
Definir objetivos
Reuniones
Seguimiento
Memoria
Análisis
Especificar requisitos
Analizar requisitos
Definir el modelo del
dominio
Diseño
Prototipos web
Base de datos
Arquitectura Software
Construcción
Base de datos
Persistencia
Lógica de negocio
Controladores
Presentación
Pruebas
Diseño
Verificación
Formación
41
Figura 17: Diagrama de Gantt
42
4.4. Resultado final
El tiempo de casi todas las tareas se corresponde con su planificación inicial, dado que
durante el período de prácticas en la empresa ya había empezado a ver y manejar algunas
de las tecnologías empleadas en este proyecto.
El tiempo restante planificado para la formación, se ha invertido en el estudio de la
tecnología Spring Framework y en profundizar en algunos aspectos de las demás
tecnologías.
Al ser mi primera experiencia en realizar un proyecto real, no fue una planificación
ajustada al 100% como es en la mayor parte de los casos. Ha habido algunos pequeños
desfases entre la planificación inicial y la final. Estos desfases son muy poco significativos,
y además se compensaron con otros donde la planificación fue muy pesimista.
4.4.1. Comparación entre el tiempo estimado y el real
Tarea Tiempo estimado
Tiempo real
Desfase
Análisis 40 35 -5 - Especificación de requisitos 20 15 - 5 - Analizar requisitos 15 15 0 - Definir el modelo del dominio 5 5 0
Diseño 25 20 -5 - Base de datos 15 10 -5 - Prototipos de la interfaz 5 5 0 - Arquitectura software 5 5 0
Construcción 126 118 -8 - Base de datos 20 12 -8 - Población de la BD 6 6 0 - Capa de persistencia 25 30 5 - Lógica de negocio 25 30 5 - Capa de presentación 30 30 0 - Construcción de la interfaz 20 10 -10
Pruebas 25 25 0 - Diseño de casos de prueba 10 10 0 - Verificación de pruebas 15 15 0
Gestión del proyecto 44 57 13 - Definir los objetivos 10 10 0 - Reuniones con el tutor 4 6 2 - Planificación 6 6 0 - Entrevistas con el cliente 6 10 4 - Seguimiento 3 5 2 - Confección de la memoria 15 20 5
Formación 40 50 10 Total horas 300 305 5
Tabla 3: Comparación entre tiempos
43
Figura 18: Gráfico de comparación de tiempos
4.4.2. Justificación de los desfases
Uno de los desfases de la planificación se produjo en el apartado de gestión del proyecto
que fue un total de 13 horas. La estimación de las horas de reunión tanto con el cliente
como el tutor, fue un poco optimista. También se han visto afectadas las horas planificadas
para la confección de la memoria debido a mi poca experiencia en la confección de este
tipo de documentos.
Por otra parte, el aumenta de la duración del proceso de formación debido a los problemas
que han surgido durante el desarrollo y al desconocimiento de las tecnologías utilizadas.
La notable disminución del tiempo planificado al inicio para la construcción de la interfaz
de usuario debido al uso de la tecnología Richfaces para este cometido, que afectó de
forma positiva a esta tarea.
El diseño y construcción de la base de datos que realmente no requería tanto tiempo
debido a la reutilización de muchas de las tablas que pertenecían al antiguo modelo de
datos.
0
20
40
60
80
100
120
140
40 25
126
25 44 40 35
20
118
25
57 50
Tiempo estimado Tiempo real
44
4.5. Problemas afrontados
Una de las tareas más significativas durante el desarrollo de este proyecto fue la
formación, debido a la multitud de tecnologías usadas y que eran totalmente desconocidas
para mí, como es el caso de Hibernate, JavaServer Faces, Facelets, Jasperrreports y el más
destacable entre todos Spring Framework y su parte de seguridad.
Uno de los problemas que he tenido durante el desarrollo fue haciendo uso de Maven
como gestor de proyectos, concretamente en la gestión que realiza éste de los repositorios
(empresarial, central y local). Al principio empecé utilizando el repositorio privado de la
empresa Suma Info S.L. Al ver que no podía acceder desde fuera, tuve que modificar este
último por otros repositorios centrales de Maven para la gestión de las librerías.
Al emplear Jasperrreports para generar los informes necesitaba la versión 4.5.0, sin
embargo no se encontraba en los repositorios centrales de Maven. Causa por la cual tuve
que volver a cambiar los repositorios declarados en el fichero de configuración de Maven.
En las relaciones de asociación (ManyToOne) en Hibernate por defecto realiza una
recuperación temprana. Para evitar la carga en memoria de todos los objetos implicados
en una relación de este tipo, configuré las clases entidad (del modelo) con el objetivo de
que la recuperación sea tardía o perezosa. En algunas de las consultas HQL realizadas
accedía a atributos de objetos que pertenecían a este tipo de relación. Todo ello, me llevó a
tardar en detectar que estos objetos no estaban inicializados.
La solución tomada en este caso, aunque puede que no sea la más óptima, fue cambiar el
modo de recuperación en aquellos casos donde se necesitaba y dejar el resto como estaba
al principio.
45
CONCLUSIONES En cuanto a funcionalidad, se han alcanzado todas las metas puestas al principio del
proyecto. Como resultado final se ha obtenido una aplicación web que ofrece al usuario
una interfaz intuitiva sin mucha complejidad y de fácil manejo en la que se ha logrado
cubrir las funcionalidades deseadas por el cliente, que le permiten realizar una gestión
completa de sus proyectos y tiempos así como de la mayoría de gestiones que se
realizaban con la antigua aplicación de la que disponía al principio.
Cabe mencionar el gran número de conocimientos que se han adquirido durante el
desarrollo de este Trabajo Fin de Grado debido al manejo de todas las tecnologías que se
han usado para la ejecución del mismo y que fueron impuestas en su totalidad por el
cliente.
El enfrentamiento a los distintos problemas surgidos durante todo proceso de
construcción de la aplicación, el tiempo invertido en la búsqueda de las soluciones que
mejor se adapten a cada caso y su implantación, con todo ello aprendí a tomar mis propias
decisiones y asumir la responsabilidad de sus consecuencias.
El proceso de formación que fue muy largo sobre todo con Spring Framework y la
navegación en un mundo extenso de nuevas tecnologías ha merecido la pena para adquirir
nuevas experiencias en el mundo laboral.
La realización de un proyecto real en un entorno empresarial ha sido un punto clave para
ampliar y poner a prueba mis conocimientos adquiridos durante toda la carrera.
En general se han logrado los objetivos a nivel de proyecto, se han cumplido mis
propósitos personales y a nivel educativo fue un proyecto muy enriquecedor.
Posibles mejoras
Los siguientes puntos son algunas mejoras que pueden ser añadidas a la aplicación en el
futuro:
1) Ofrecer la posibilidad de generar informes parametrizados: debido a la falta de
tiempo, en el desarrollo del proyecto se han tenido en cuenta los informes de
facturas que era uno de los requisitos que se habían establecido al inicio. Cabe la
posibilidad de ampliar la funcionalidad de esta aplicación y permitir la generación
de informes en formato PDF atendiendo a ciertos parámetros que introduce el
usuario, por ejemplo: ver sus registros de tiempo para un determinado proyecto.
2) Mejorar la navegación en todas las páginas: se pueden incluir “migas de pan” para
que el usuario sepa en cualquier momento dónde se encuentra y la relación
jerárquica de la página donde se encuentra con el resto de la estructura de la
aplicación. Para ello, se pueden usar elementos de la librería Primefaces que
facilitan esta tarea.
46
BIBLIOGRAFÍA
FRANCISCO JOSÉ GARCÍA IZQUIERDO. Apuntes de la asignatura Programación de
aplicaciones Web.
ARTURO JAIME ELIZONDO. Apuntes de la asignatura Diseño de bases de datos
ELMASRI RAMEZ y NAVATHE SHAMKANT. Fundamentos de Sistemas de Bases de Datos. 3ªEd.
GRAIG WALLS. Spring. 3ªEd.
PAUL TEPPER FISHER and BRIAN D. MURPHY. Spring persistence with hibernate.
MAX KATZ y ILYA SHAIKOVSKY. Practical Richfaces. 2ªEd.
TEODOR DANCIU and LUCIAN CHIRITA. The definitive guide to JasperReports. Referencias Web:
Richfaces: http://www.jboss.org/richfaces http://livedemo.exadel.com/richfaces-demo/richfaces/dataTableScroller.jsf?s=glassX
Hibernate: http://docs.jboss.org/hibernate/core/3.5/reference/es-ES/html/
Jasperreports: http://community.jaspersoft.com/project/jasperreports-library
Spring: http://www.springhispano.org/
http://www.springsource.org/spring-framework
UNIVERSIDAD DE LA RIOJA
FACULTAD DE CIENCIAS, ESTUDIOS AGROALIMENTARIOS E INFORMÁTICA
GRADO EN INGENIERÍA INFORMÁTICA
Aplicación web para el control de proyectos en la empresa
Suma Info S.L. Manual de usuario
Junio de 2013
Realizado por
Naziha Ayachi Majait
Dirigido por
Francisco José García Izquierdo
ÍNDICE
SOBRE LISTADOS .................................................................................................................... 1
1. PROYECTOS....................................................................................................................... 2
1.1. Crear nuevo proyecto ............................................................................................................ 2
1.2. Asignar técnicos a proyecto ................................................................................................ 2
1.3. Detalles del proyecto ............................................................................................................. 3
2. REGISTRO DE TIEMPOS ................................................................................................ 3
2.1. Registrar tiempo ..................................................................................................................... 4
3. GASTOS ............................................................................................................................... 4
3.1. Imputar gastos a proyecto .................................................................................................. 5
4. TÉCNICOS ........................................................................................................................... 5
4.1. Dar de baja a un técnico ....................................................................................................... 6
4.2. Categorías de un técnico ...................................................................................................... 6
5. CLIENTES ........................................................................................................................... 7
6. FACTURAS ......................................................................................................................... 7
6.1. Crear nuevo factura ............................................................................................................... 7
6.2. Generar informe de facturaciones ................................................................................... 8
6.3. Editar una factura ................................................................................................................... 9
7. Categorías .......................................................................................................................... 9
7.1. Editar categoría .....................................................................................................................10
7.2. Tarifas de una categoría .....................................................................................................10
1
SOBRE LISTADOS
En cualquier listado que aparece en las páginas de la aplicación, puede acceder a distintas
funciones. Utilizando el menú que aparece al pulsar sobre la cabecera de cada columna
puede:
1) Ordenar de forma ascendente o descendente, que puede llevar a cabo de otra
forma, simplemente pulsando sobre la cabecera de la columna deseada.
2) Agrupar o desagrupar por una columna.
3) Mostrar u ocultar columnas mediante la opción “Columns” del mismo menú.
4) Navegar por las distintas páginas del listado. En el pie del cada listado se muestran los botones de navegación que le permiten moverse de forma rápida por los distintos elementos del listado.
2
1. PROYECTOS
En este apartado puede gestionar todo lo relacionado con los proyectos de la empresa. En el listado de proyectos se muestran los siguientes campos: la denominación del proyecto, el cliente y el estado del proyecto (finalizado o no).
Desde el listado puede realizar diferentes acciones como:
1) Utilizar los filtros para realizar búsquedas por denominación y cliente, simplemente introduciendo la cadena deseada en el campo destinado a este fin.
2) Modificar los datos básicos de un proyecto pulsando sobre .
3) Ver los detalles de un proyecto accediendo a través de .
4) Asignar técnicos al proyecto con la opción .
1.1. Crear nuevo proyecto
En la página donde se muestra el listado de proyectos, pulsando el botón se abrirá el
formulario para rellenar los datos de un nuevo proyecto.
Debe introducir los datos básicos del proyecto; denominación, plataforma, organismo, tipo
de proyecto y la fecha de propuesta. Una vez que termina este proceso debe pulsar el
botón “Guardar” y así insertar el proyecto en la base de datos y volver al listado para
comprobar que se ha introducido correctamente.
1.2. Asignar técnicos a proyecto
Pulsando el botón puede acceder a un nuevo formulario para asignar nuevos técnicos
al proyecto.
3
Para ello, debe seleccionar un técnico del listado de la parte izquierda y una categoría de
las disponibles a la derecha. Para finalizar la operación debe pulsar sobre el botón
“Asignar”.
Posteriormente podrá ver todos los técnicos asignados al proyecto en el listado que se
encuentra en parte inferior de esta página y borrar alguna asignación anterior pulsando el
botón si así lo desea. Una vez pulsado este último aparece una ventana para confirmar
la eliminación como puede observar en la siguiente figura:
1.3. Detalles del proyecto
Por otra parte, puede acceder a la opción para ver los detalles de un proyecto. Esta opción incluye los datos básicos (identificador, denominación, plataforma, tipo de proyecto, cliente, fecha de propuesta, fecha de inicio y el estado del proyecto), los tiempos registrados por todos los técnicos que participan en el desarrollo del proyecto y los gastos imputados al mismo.
En la pestaña “Tiempos registrados” puede ver los siguientes datos de cada registro: el técnico, la fecha, una descripción de la actividad realizada y por último, el número de horas. En la segunda pestaña, “Gastos del proyecto” puede ver todos los gastos que se han imputado al proyecto y consultar los datos básicos de cada uno. Los atributos que puede consultar son: la fecha, la descripción, el tipo de gasto y el importe del mismo.
2. REGISTRO DE TIEMPOS
Esta sección le permite registrar nuevos tiempos y ver todos los que haya registrado
anteriormente o filtrar la búsqueda por una fecha concreta.
En el panel que se muestra en la primera página puede acceder a filtrar sus tiempos por
una fecha. Para ello, debe pulsar sobre el icono o sobre el campo donde aparece la
fecha para seleccionar una nueva y posteriormente pulsar sobre el botón “Buscar”.
4
En caso de que quiera ver todos los tiempos que lleva registrados hasta el momento,
puede hacerlo a pulsando el botón “Ver todos”.
En cualquier caso aparecerá un listado con todos sus registros que incluye los campos de
fecha, descripción de la actividad realizada y la duración en horas.
Las acciones que incluye este listado son:
1) Los filtros para realizar búsquedas por fecha, descripción o por horas.
2) Editar un registro pulsando sobre el icono .
3) Eliminar un registro mediante la opción , que muestra un mensaje de para
confirmar o cancelar esta operación.
2.1. Registrar tiempo
Para crear un nuevo registro de tiempo debe pulsar el botón que aparece en la página
del listado de tiempos. Se abrirá un formulario donde debe introducir todos los datos
necesarios y que son: la fecha, la descripción de la tarea, número de horas, el proyecto y
por último, elegir el tipo de trabajo realizado.
Para finalizar esta operación debe pulsar sobre el botón “Guardar” para insertar el nuevo
registro y volver al listado inicial.
3. GASTOS
En esta sección se muestra un listado con todos sus gastos registrados por los proyectos
en los que haya participado. De cada gasto se muestra su fecha de registro, una
descripción, el tipo de gasto y el importe del mismo.
5
Las acciones disponibles en este listado son:
1) La opción permite editar un gasto existente.
2) La opción permite eliminar un gasto de los registrados.
3) Filtrar por fecha, descripción, tipo de gasto o importe.
3.1. Imputar gastos a proyecto
Pulsando sobre el icono se muestra un formulario donde puede crear un nuevo gasto.
Para ello, debe rellenar los datos requeridos como la fecha, el importe, el tipo de gasto y
seleccionar un proyecto de los disponibles.
4. TÉCNICOS
Le permite gestionar y mantener la información de los empleados de la empresa. De cada
empleado se muestra su nombre, apellidos, nombre de usuario y la fecha de baja (si ha
sido dado de baja).
Desde el listado de técnicos puede realizar distintas acciones como:
1) Filtrar por nombre, apellidos y usuario.
2) Modificar los datos de un técnico existente pulsando sobre el icono .
3) Ver los detalles de un técnico pulsando sobre el icono .
6
4.1. Dar de baja a un técnico
Para dar de baja a un técnico activo en la empresa debe pulsar sobre el botón para
acceder a modificar sus datos. Una vez que está en el formulario, debe seleccionar una
fecha a partir de la cual tendrá efecto la baja efectuada. Para volver a activar un técnico
que ya se había dado de baja, debe pulsar sobre el icono para abrir el calendario y
seleccionar la opción “Clean” para borrar la fecha de baja. Por último, pulsar el botón
“Editar” para guardar los cambios.
4.2. Categorías de un técnico
Mediante la opción del listado de técnicos puede acceder a sus detalles y ver todas las
categorías que se le han asignado durante su instancia en la empresa, así como efectuar
una nueva asignación.
Para asignar una categoría, debe elegir una de las disponibles, introducir el año y
finalmente pulsar el botón “Asignar”.
En el listado se muestra la categoría y el año. Puede modificar estas asignaciones eligiendo
una categoría nueva y/o introduciendo otro año distinto en sus respectivos campos del
listado, como se puede observar en la siguiente figura.
Para confirmar la modificación y guardar los datos cambiados debe pulsar sobre .
También puede optar por borrar una asignación ya existente mediante la opción .
7
5. CLIENTES
Permite gestionar toda la información referente a los clientes de la empresa; crear nuevos
y modificar los existentes. En el listado de clientes se muestran los siguientes campos: el
nombre, la dirección y el municipio.
Pulsando el icono puede acceder al formulario para crear un nuevo cliente. Los datos
necesarios para crear un nuevo cliente son: denominación, dirección, código postal, país,
provincia y municipio.
Para modificar los datos de un cliente deberá acceder pulsando sobre el botón , acción
disponible en el listado de los clientes.
6. FACTURAS
Le permite gestionar y mantener todas las facturaciones realizadas por los proyectos de la
empresa. En el listado de las facturas se muestra el número de factura, la fecha, el proyecto
y el importe total.
Las posibles acciones para cada factura del listado son editar y eliminar .
6.1. Crear nuevo factura
Pulsando sobre el icono puede acceder a crear una nueva factura. Como datos
necesarios debe seleccionar la fecha y el proyecto para facturar sus gastos.
Una vez seleccionado el proyecto aparecerán dos listas; la primera corresponde a los
gastos del proyecto para elegir los que desea incluir en la factura y en la segunda
aparecerán los gastos que vaya seleccionando.
8
Usando los botones que aparecen entre las dos listas puede:
- Añadir todos los gastos pulsando el boton “Añadir todos”.
- Seleccionar algunos gastos y añadirlos pulsando sobre la opción “Añadir”.
De manera similar puede borrar todos los gastos incluidos en la segunda lista o
seleccionar alguno(s) concreto(s) y borrarlo(s) usando los botones “Borrar” y “Borrar
todos”.
Una vez seleccionados los gastos que desea incluir en la factura, puede optar por terminar
el proceso y volver al listado de facturas o avanzar a la siguiente página pulsando el botón
“Aceptar” para incluir los honorarios.
Para crear un nuevo honorario debe seleccionar la fecha, el técnico, el concepto e
introducir una descripción y el número de horas. Los honorarios que va introduciendo se
reflejarán en la tabla que se sitúa en la parte superior de la página.
También puede eliminar algún honorario que no desea incluir en la factura pulsando sobre
.
Para finalizar el proceso de facturación debe pulsar el botón “Terminar” para guardar la
factura y volver al listado principal.
6.2. Generar informe de facturaciones
Para descargar un informe con todas las facturaciones realizadas en la aplicación en
formato PDF, debe pulsar el botón situado en la cabecera de la lista de facturas que se
indica en la imagen que sigue.
Posteriormente se descargará un documento con nombre “Informe_facturas.pdf” que
contiene toda la información de las facturas. Este informe incluye de cada factura los
campos: fecha, número de factura, código del proyecto, el IVA y el total.
9
6.3. Editar una factura
Para editar una factura, tiene que acceder pulsando el botón , que abre una primera
página con la información básica de la factura (número, fecha y proyecto) y una lista con
todos los gastos incluidos en la factura en el momento de su creación.
En esta parte, dispone de una lista desplegable con todos los gastos del proyecto para
incluir otros nuevos que no estén en la factura. Cada vez que selecciona un gasto debe
guardarlo pulsando el botón “Añadir”.
Por otra parte, podrá eliminar cualquier gasto de los que haya añadido o alguno de los que
ya estaban asignados al principio al pulsar el botón y aceptar la confirmación de la
eliminación.
Una vez terminado este proceso, debe comprobar los datos y pulsar el botón “Ver líneas”
para acceder a añadir nuevos honorarios a la factura.
Para crear un nuevo honorario debe seleccionar la fecha, el técnico, el concepto e
introducir una descripción y el número de horas. Los honorarios que va introduciendo se
reflejarán en la tabla sita en la parte superior de la página. A través de esta tabla puede
eliminar honorarios pulsando el botón destinado a este fin .
7. Categorías
En esta página se muestran todas las categorías en un listado. Puede añadir una nueva
categoría insertando el nombre en el formulario que se sitúa en la parte superior de la
página y pulsar el botón “Guardar”.
Desde el listado de categorías puede realizar distintas acciones como:
1) Filtrar por denominación.
2) Modificar una categoría existen pulsando sobre el icono .
3) Ver las tarifas de una categoría pulsando sobre .
10
7.1. Editar categoría
Para modificar una de las categorías que aparecen en el listado, debe situarse dentro del
campo de la denominación y modificar su contenido. Finalmente confirmar la modificación
realizada pulsando sobre el icono .
7.2. Tarifas de una categoría
Para ver las tarifas que se le han asignado a una categoría durante el paso del tiempo, debe
pulsar sobre el icono .
Acto seguido, aparecerán toda la información relacionada con las tarifas de la categoría
seleccionada incluyendo el año y el importe de las mismas. Las acciones que puede
ejecutar sobre estas tarifas son:
- Eliminar la tarifa pulsando sobre el icono .
- Modificar su contenido en el propio campo y pulsar el icono para guardar los
cambios.
También puede asignar nuevas tarifas a una categoría usando el formulario que se sitúa al
principio de la página.
Inicialmente debe seleccionar la categoría a la que quiere asignar la tarifa e introducir el
año y el importe deseado. Una vez que termina de rellenar estos campos debe insertar esta
asignación en la base de datos pulsando sobre el botón “Guardar”.