Está en la página 1de 138

FACULTAD DE INFORMÁTICA

Departamento de Computación

Proyecto Fin de Carrera de Ingenierı́a


Informática

‘Creación de un sistema de planificación completa de trabajo y


data-mining avanzado para la gestión de actividades laborales
mediante interfaces dinámicas’

Autor: Jorge López Fernández


Director: José Juan González Alonso
Tutor: José Marı́a Casanova Crespo

A Coruña, 3 de julio de 2010


Información general del proyecto

Tı́tulo del proyecto: Creación de un sistema de planificación completa de


trabajo y data-mining avanzado para la gestión de
actividades laborales mediante interfaces dinámicas

Clase de proyecto: Proyecto clásico de ingenierı́a

Nombre del autor: Jorge López Fernández

Nombre del director: José Juan González Alonso

Nombre del tutor: José Marı́a Casanova Crespo

Miembros del tribunal:

Miembros suplentes:

Fecha de lectura:

Calificación:
RESUMEN

Las aplicaciones de anotación de trabajo han ganado una relevancia notable en los últi-
mos años debido a la actual tendencia a trasladar todas las mecánicas habituales de los
entornos empresariales al ámbito ofimático. Esta filosofı́a es la perseguida por la aplicación
PhpReport, un programa web de software libre creado por la empresa Igalia. La primera
versión de dicha herramienta fue creada en el año 2003 y en año 2009 se decidió reimple-
mentarla por completo.
Este proyecto clásico de ingenierı́a consiste en la ampliación de la nueva versión de dicha
aplicación web de software libre para anotación de trabajo, añadiéndole nuevas funcionali-
dades y actualizando sus interfaces. Los objetivos concretos de esta ampliación de su nueva
versión son dotar a PhpReport de planificación a corto y largo plazo, añadirle capacidades
avanzadas de extracción de datos y un nuevo conjunto de interfaces web dinámicas.
Al dotarla de capacidades para anotar la planificación se pretende integrar dicho aparta-
do con la anotación de tareas, permitiendo un seguimiento más sencillo de la evolución de
los proyectos. Dicho seguimiento se podrá realizar a dos niveles: una planificación a largo
plazo (planificación completa del proyecto) y una planificación a corto plazo (planificaciones
periódicas del trabajo diario).
La extracción de datos avanzada persigue una obtención sencilla de informes, tanto
generales como de elementos individuales, de múltiples tipos. Para ello se persigue crear
un motor de extracción de información de un ámbito general y configurable en base a
parámetros, de manera que no sea necesario un método distinto para cada tipo de informe
requerido.
Un nuevo conjunto de interfaces dinámicas permitirán abandonar las actuales interfaces
web de PhpReport, todas de enfoque estático y por lo tanto susceptibles de necesitar un
gran número de recargas con cambios de información en el lado del servidor. El empleo
de ((widgets)) dinámicos permitirá dotar a la aplicación de una apariencia más moderna y
proporcionar una mejor experiencia al usuario, al cual se le evitará la recarga de la página
cuando requiere o guarda un conjunto de datos.
Una vez logrados estos tres objetivos se obtendrá una aplicación de anotación de trabajo
totalmente libre y funcional para el entorno empresarial, a la cual se planea realizar una
serie de mejoras y añadidos en el futuro con el objetivo tanto de mejorar su apariencia de
cara al usuario final como de aumentar la potencia de sus nuevas capacidades y mejorar su
rendimiento.
PALABRAS CLAVE

PhpReport Data-mining

Igalia PHP

Software libre JavaScript

Time-tracking PostgreSQL

Anotación de trabajo ExtJS

Planificación de trabajo AJAX

Extracción de datos Programación Orientada a Objetos


AGRADECIMIENTOS

Me gustarı́a agradecer a todos los miembros de Igalia la excelente acogida que me han
brindado durante todo el tiempo que he tenido la suerte de trabajar con ellos, gracias a los
cuales he tenido una de las mejores experiencias de toda mi vida, tanto en lo profesional
como en lo personal. Muy especialmente me gustarı́a agradecer a Jota, Jacobo y Chema
su apoyo, confianza y ayuda durante la elaboración de este trabajo, y por brindarme la
oportunidad de dar mis primeros pasos en el mundo laboral.
Índice general

Índice general I

Índice de tablas IV

Índice de figuras V

Índice de código VII

1. Prólogo 1
1.1. Marco del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Objetivos globales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3. Contribuciones logradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4. Estructura de la memoria . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2. Introducción 4
2.1. Igalia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. PhpReport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3. Herramientas y entorno de trabajo . . . . . . . . . . . . . . . . . . . . . . 5
2.3.1. Entorno informático básico de trabajo . . . . . . . . . . . . . . . . 5
2.3.2. Lenguajes, bibliotecas, modelos y enfoques empleados . . . . . . . . 5
2.3.3. Herramientas software empleadas . . . . . . . . . . . . . . . . . . . 20
2.3.4. Herramientas software testeadas . . . . . . . . . . . . . . . . . . . 22
2.4. Metodologı́a de trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4.1. Descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4.2. Caracterı́sticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.4.3. Aplicación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3. Estado del arte 25


3.1. Evolución de las aplicaciones privativas . . . . . . . . . . . . . . . . . . . . 25
3.1.1. Coordinación de múltiples fuentes . . . . . . . . . . . . . . . . . . 26
3.1.2. Extracción de informes y minerı́a de datos . . . . . . . . . . . . . . 27
3.1.3. Integración en el entorno empresarial . . . . . . . . . . . . . . . . . 28
3.1.4. Temporizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.1.5. Compatibilidad multi-plataforma . . . . . . . . . . . . . . . . . . . 29
3.1.6. Interfaces web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

i
ÍNDICE GENERAL ii

3.1.7. Capacidades de monitorización . . . . . . . . . . . . . . . . . . . . 30


3.1.8. Capacidades locales . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.1.9. Versiones gratuitas . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.2. Evolución de las aplicaciones libres . . . . . . . . . . . . . . . . . . . . . . 31
3.2.1. dotProject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.2.2. Rachota . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.3. MyTime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
3.2.4. Project Hamster . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4. Planificación de trabajo 33
4.1. Objetivos y descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1.1. Objetivos concretos . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.1.2. Descripción general . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.2. Análisis y diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.2.1. Planificación a corto plazo . . . . . . . . . . . . . . . . . . . . . . 35
4.2.2. Planificación a largo plazo . . . . . . . . . . . . . . . . . . . . . . 36
4.2.3. Estructura final de la BD . . . . . . . . . . . . . . . . . . . . . . . 38
4.3. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4.3.1. Creación de la base de datos . . . . . . . . . . . . . . . . . . . . . 41
4.3.2. Creación de los Value Object (VO) . . . . . . . . . . . . . . . . . . 41
4.3.3. Creación de los Data Access Object (DAO) . . . . . . . . . . . . . 42
4.3.4. Creación de las acciones . . . . . . . . . . . . . . . . . . . . . . . 43
4.3.5. Creación de las fachadas . . . . . . . . . . . . . . . . . . . . . . . 46
4.4. Pruebas y resultados obtenidos . . . . . . . . . . . . . . . . . . . . . . . . 46
4.4.1. Pruebas de VOs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
4.4.2. Pruebas de DAOs . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
4.4.3. Pruebas de acciones . . . . . . . . . . . . . . . . . . . . . . . . . . 48

5. Extracción de datos avanzada 49


5.1. Objetivos y descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.1. Objetivos concretos . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.1.2. Descripción general . . . . . . . . . . . . . . . . . . . . . . . . . . 49
5.2. Análisis y diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
5.3. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
5.3.1. Funciones básicas de extracción de datos . . . . . . . . . . . . . . . 51
5.3.2. Acciones especı́ficas . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.4. Pruebas y resultados obtenidos . . . . . . . . . . . . . . . . . . . . . . . . 59

6. Creación de interfaces web dinámicas 61


6.1. Objetivos y descripción . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.1.1. Objetivos concretos . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.1.2. Descripción general . . . . . . . . . . . . . . . . . . . . . . . . . . 61
6.2. Análisis y diseño . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.2.1. Funcionalidades esenciales . . . . . . . . . . . . . . . . . . . . . . 62
6.2.2. Organización de las interfaces . . . . . . . . . . . . . . . . . . . . 63
6.3. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
ÍNDICE GENERAL iii

6.3.1. Interfaces en torno a Task . . . . . . . . . . . . . . . . . . . . . . 65


6.3.2. Interfaces en torno a User . . . . . . . . . . . . . . . . . . . . . . 69
6.3.3. Interfaces en torno a Customer . . . . . . . . . . . . . . . . . . . . 74
6.3.4. Interfaces en torno a Area . . . . . . . . . . . . . . . . . . . . . . 74
6.3.5. Interfaces en torno a Project . . . . . . . . . . . . . . . . . . . . . 77
6.3.6. Interfaces para la planificación . . . . . . . . . . . . . . . . . . . . 80
6.4. Pruebas y resultados obtenidos . . . . . . . . . . . . . . . . . . . . . . . . 97
6.4.1. Pruebas formales . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.4.2. Versión de pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . 99

7. Limitaciones, mejoras potenciales y conclusiones globales 100


7.1. Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
7.1.1. Planificación de trabajo . . . . . . . . . . . . . . . . . . . . . . . . 100
7.1.2. Extracción de datos avanzada . . . . . . . . . . . . . . . . . . . . . 100
7.1.3. Creación de interfaces web dinámicas . . . . . . . . . . . . . . . . 100
7.2. Mejoras potenciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
7.2.1. Planificación de trabajo . . . . . . . . . . . . . . . . . . . . . . . . 101
7.2.2. Extracción de datos avanzada . . . . . . . . . . . . . . . . . . . . . 101
7.2.3. Creación de interfaces web dinámicas . . . . . . . . . . . . . . . . 101
7.3. Conclusiones globales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

A. Diagramas adicionales 104


A.1. Diagramas Entidad-Relación . . . . . . . . . . . . . . . . . . . . . . . . . 105
A.2. Diagramas UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

B. Código 113
B.1. Planificación de trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
B.2. Extracción de datos avanzada . . . . . . . . . . . . . . . . . . . . . . . . . 116

C. Glosario de acrónimos 120

Referencias 122
Índice de tablas

2.1. Herramientas software empleadas . . . . . . . . . . . . . . . . . . . . . . . 21


2.2. Herramientas software testeadas . . . . . . . . . . . . . . . . . . . . . . . 22

iv
Índice de figuras

2.1. Funcionamiento básico de las metodologı́as de desarrollo ágiles . . . . . . . 23

4.1. Diagrama E-R simplificado del modelo final de la BD . . . . . . . . . . . . 38


4.2. Diagrama de secuencia de una acción y sus plugins . . . . . . . . . . . . . 40
4.3. Diagrama UML de los VO creados para la planificación . . . . . . . . . . . 42
4.4. Diagrama UML de los DAO creados para la planificación . . . . . . . . . . 44
4.5. Diagrama de los métodos nuevos para la planificación . . . . . . . . . . . . 45
4.6. Diagrama de secuencia de creación de una Task Story . . . . . . . . . . . 47

5.1. Diagrama de secuencia de obtención de un informe User-Story . . . . . . . 54


5.2. Ejemplo de informe User-Story . . . . . . . . . . . . . . . . . . . . . . . . 55
5.3. Ejemplo del informe de horas extra y vacaciones pendientes . . . . . . . . . 58

6.1. Barra lateral de la interfaz web de PhpReport . . . . . . . . . . . . . . . . 65


6.2. Interfaz web para las operaciones CRUD sobre las tareas . . . . . . . . . . 66
6.3. Diagrama de secuencia del salvado de las tareas de un usuario . . . . . . . 68
6.4. Interfaz web con los detalles de usuario . . . . . . . . . . . . . . . . . . . . 70
6.5. Interfaz web para evaluación de los usuarios . . . . . . . . . . . . . . . . . 71
6.6. Interfaz web para la obtención del informe de horas extra . . . . . . . . . . 72
6.7. Interfaz web para la gestión de los usuarios y sus históricos . . . . . . . . . 75
6.8. Interfaz web para la gestión de los clientes y sus sectores . . . . . . . . . . 76
6.9. Interfaz web para la gestión de las áreas . . . . . . . . . . . . . . . . . . . 78
6.10. Interfaz web para la gestión de los proyectos . . . . . . . . . . . . . . . . . 79
6.11. Interfaz web para ver detalles de los proyectos . . . . . . . . . . . . . . . . 81
6.12. Interfaz web de evaluación de proyectos . . . . . . . . . . . . . . . . . . . 82
6.13. Interfaz web de resumen de proyectos . . . . . . . . . . . . . . . . . . . . 83
6.14. Interfaz web de resumen de planificación a corto plazo . . . . . . . . . . . 85
6.15. Interfaz web de detalles de Iteration . . . . . . . . . . . . . . . . . . . . . 86
6.16. Interfaz web del formulario de Iteration . . . . . . . . . . . . . . . . . . . . 87
6.17. Interfaz web de detalles de Story . . . . . . . . . . . . . . . . . . . . . . . 89
6.18. Interfaz web del formulario de Story . . . . . . . . . . . . . . . . . . . . . 90
6.19. Interfaz web de resumen de planificación a largo plazo . . . . . . . . . . . 91
6.20. Interfaz web de detalles de Module . . . . . . . . . . . . . . . . . . . . . . 93
6.21. Interfaz web del formulario de Module . . . . . . . . . . . . . . . . . . . . 94
6.22. Interfaz web de detalles de Section . . . . . . . . . . . . . . . . . . . . . . 95

v
ÍNDICE DE FIGURAS vi

6.23. Interfaz web del formulario de Section . . . . . . . . . . . . . . . . . . . . 96

A.1. Diagrama E-R del modelo final de la BD . . . . . . . . . . . . . . . . . . . 105


A.2. Diagrama UML del modelo final de la BD empleado en tedia2sql . . . . . . 106
A.3. Diagrama UML de todos los DAOs existentes en PhpReport (1/4) . . . . . 107
A.4. Diagrama UML de todos los DAOs existentes en PhpReport (2/4) . . . . . 108
A.5. Diagrama UML de todos los DAOs existentes en PhpReport (3/4) . . . . . 109
A.6. Diagrama UML de todos los DAOs existentes en PhpReport (4/4) . . . . . 110
A.7. Diagrama UML de todos los VO existentes en PhpReport . . . . . . . . . . 111
A.8. Diagrama UML de todas las fachadas existentes en PhpReport . . . . . . . 112
Índice de código

5.1. Seudocódigo del cálculo de horas extra . . . . . . . . . . . . . . . . . . . . 57


B.1. Fragmento de un DAO de PostgreSQL de ejemplo . . . . . . . . . . . . . . 113
B.2. Fragmento de la acción para obtener las horas extra . . . . . . . . . . . . . 116
B.3. Fragmento de la acción para obtener las horas de vacaciones pendientes . . 119

vii
Capı́tulo 1

Prólogo

1.1. Marco del proyecto


Las aplicaciones de anotación de trabajo han ganado una relevancia muy notable en los
últimos años debido a la actual tendencia a trasladar todas las mecánicas habituales de los
entornos empresariales al ámbito ofimático. Por ello si hace años no era extraño que los
empleados tuvieran que fichar a la entrada y salida del trabajo ahora tampoco lo es que su
labor realizada sea anotada en un servidor central de la empresa.
Dichas aplicaciones han evolucionado desde que comenzaran a surgir a principios de
los años 90. Lo que comenzó siendo una mera agenda personal para anotar tanto nuestras
futuras actividades como las ya realizadas acabó siendo en muchas ocasiones una aplicación
centralizada en la cual todos los trabajadores de una empresa anotaban su trabajo, pudiendo
posteriormente extraerse informes o incluso gestionarse aspectos como la facturación por
hora de trabajo al cliente.
También según los puestos de trabajo fueron ganando en heterogeneidad, tanto por
la proliferación de entornos ofimáticos en muy diversos perfiles de trabajadores como por
la cada vez mayor oferta de productos software y hardware, se hizo esencial la obtención
de una aplicación lo más independiente posible. La explosión de internet propició que las
aplicaciones web se perfilaran como la solución perfecta a dicho problema, convirtiéndose
en uno de los pilares para las aplicaciones de anotación de trabajo centralizadas.
La explosión de internet también provocó una popularización del software libre muy
importante al convertirse en el principal vehı́culo para la comunicación de sus distintas
comunidades y para la distribución del propio software. Pero, a pesar de ello, ambos resul-
tados no lograron converger de una manera realmente eficaz, por lo que durante años no
existió ninguna herramienta de anotación de trabajo libre de cierta calidad.
Como consecuencia, la empresa Igalia, basada en el software libre, decidió crear una
aplicación web de dichas caracterı́sticas adecuada a sus propias necesidades, con lo que en
el año 2003 nació PhpReport. Dicho programa ha sufrido diversas mejoras y modificaciones
desde su creación, pero manteniendo en esencia el mismo código y estructura en todo
momento. Tras seis años con múltiples parches el código ha comenzado a resultar caótico
e insostenible, por lo que se decidió realizar una reimplementación por completo en base a
una estructura de capas.
A finales del año 2009 vio la luz ese nuevo modelo de PhpReport, el cual conservaba
todas las caracterı́sticas del código central de su anterior versión pero ahora de un modo
mucho más limpio, modular, mantenible y fácilmente ampliable. Debido al éxito de dicho

1
1.2. Objetivos globales 2

proceso se decidió ampliar la aplicación con funcionalidades adicionales, además de renovar


totalmente sus interfaces web, las cuales ya habı́an quedado anticuadas con el paso de los
años, empleando esta vez elementos dinámicos en ellas. En este contexto de ampliación de
la aplicación PhpReport es donde se enmarca este proyecto.

1.2. Objetivos globales


Podemos resumir inicialmente los objetivos globales del proyecto de ampliación de Php-
Report del siguiente modo:

Capacidades de planificación: se pretende dotar a PhpReport de capacidades de


almacenamiento de planificaciones a corto y largo plazo, permitiendo relacionar ambas
con el trabajo almacenado, y también los dos ámbitos de planificación entre ellos.

Soporte para extracción de datos avanzada: la gran cantidad de información


almacenada en PhpReport la convierte en una aplicación idónea para la extracción de
informes dentro de la empresa, tanto sobre elementos individuales como generales,
por lo que se pretende dotar al programa de un motor de extracción de información
lo más potente posible.

Interfaces web dinámicas: el conjunto de interfaces web anterior de PhpReport


ya ha sufrido el paso de los años, quedando anticuado al lado de aplicaciones web
más recientes con contenidos ricos, además de comenzar a resultar incómodo por el
manejo de cada vez más funcionalidades sin sufrir un rediseño, por lo que se pretende
crear un conjunto nuevo de interfaces web que aprovechen las tecnologı́as dinámicas.

Cada uno de los capı́tulos centrales del documento (el capı́tulo 4 en la página 33,
el 5 en la página 49 y el 6 en la página 61) recoge con mayor detalle las caracterı́sticas
de cada uno de estos objetivos globales.

1.3. Contribuciones logradas


Gracias a este proyecto se ha logrado una aplicación de anotación de trabajo totalmente
libre y funcional para el entorno empresarial. Esta aplicación incluye además capacidades
para vincular una planificación previamente realizada mediante ella misma sobre un proyecto
con el trabajo relacionado con él que se vaya introduciendo, facilitando su seguimiento y
la obtención de información sobre él, además de la coordinación entre los miembros de la
empresa gracias a la integración total en la misma aplicación.
Las capacidades de extracción de datos avanzada facilitan la recuperación de infor-
mes sobre muy distintos elementos, propiciando además su ampliación, mantenimiento y
modificación de una manera sencilla al emplear un método general basado en parámetros
configurables.
El conjunto de interfaces dinámicas facilitan el trabajo al usuario final al proporcionar
((widgets)) de uso intuitivo que no requieren la recarga de la página con el envı́o o petición
de un conjunto de datos. Además proporcionan un aspecto más moderno y compacto a la
aplicación frente a los formularios estáticos que empleaba anteriormente.
1.4. Estructura de la memoria 3

Todos estas mejoras se han realizado respetando su estructura por capas, lo que hace
que el código sea limpio, modular y fácilmente ampliable y ((debugueable)), además de estar
totalmente documentado e incorporar pruebas formales en todos los fragmentos de código
no triviales a todos los niveles.

1.4. Estructura de la memoria


Este documento se encuentra organizado en siete capı́tulos del siguiente modo:

1. Prólogo: este capı́tulo, en el cual realizamos una introducción a la propia memoria y


al contexto del proyecto realizado.

2. Introducción: en él se recoge una introducción al proyecto, las condiciones de tra-


bajo en que se realizó y el listado de todas las tecnologı́as, enfoques y metodologı́as
empleados y/o evaluados para su realización.

3. Estado del arte: antes de realizar el propio trabajo se procedió a contemplar el


estado actual y la evolución de otras aplicaciones de finalidad similar ya existentes en
el mercado.

4. Planificación de trabajo: en él recogemos todo lo relativo al primer objetivo del


proyecto, la adición de capacidades de planificación a PhpReport.

5. Extracción de datos avanzada: describe todo el segundo objetivo, la creación del


soporte para la extracción de datos avanzada.

6. Creación de interfaces web dinámicas: como su nombre indica, recoge todo el


proceso de generación del nuevo conjunto de interfaces web de PhpReport, el último
de los objetivos.

7. Limitaciones, mejoras potenciales y conclusiones globales: en este último capı́tu-


los listaremos aquellos aspectos que no han logrado todo el potencial inicialmente
deseado, ası́ como diversos modos de mejorar la aplicación en el futuro, además de
exponer las conclusiones globales extraı́das del proyecto.

Se incluyen también una serie de apéndices que buscan complementar todo el contenido
anterior:

A. Diagramas adicionales B. Código C. Glosario de acrónimos


Capı́tulo 2

Introducción

Debido a que el proyecto se realizó en un contexto empresarial este capı́tulo está dedi-
cado a describir dicho entorno de trabajo, tanto desde el punto de vista social (descripción
de la empresa, su filosofı́a y perfil de los integrantes) como el organizativo (la metodologı́a
de trabajo empleada) o el técnico (las herramientas, bien software o hardware, relacionadas
con el trabajo realizado).

2.1. Igalia
Igalia [1] es una empresa de desarrollo software creada en el año 2001. Aunque ini-
cialmente se encontraba únicamente en la ciudad de A Coruña (oficina a la cual acudió el
alumno en numerosas ocasiones), actualmente ha adoptado una filosofı́a de trabajo distri-
buido, poseyendo otra oficina en Pontevedra y diversos empleados que trabajan de manera
remota en otras localizaciones geográficas.
Tal y como reza en la descripción que podemos leer en su web, la empresa Igalia tiene
como sus pilares fundamentales:

• El trabajo cooperativo entre todos sus miembros y una filosofı́a de cooperación asam-
blearia.
• Compartición de responsabilidades entre sus integrantes.
• Igualdad de condiciones entre los trabajadores.
• Prioridad máxima al desarrollo en software libre.
• Innovación en todos los campos, aunque siempre centrándose en el mundo del software
libre.

2.2. PhpReport
La aplicación alrededor de la cual gira este proyecto era en su versión anterior una
aplicación web implementada totalmente en PHP. Fue creada por Enrique Ocaña en el
año 2003, y desde entonces ha sido empleada en todo momento por los trabajadores de
la empresa para registrar el trabajo realizado. Además, en el año 2005 fue publicada bajo
licencia General Public License (GPL), y ha experimentado en estos años diversas mejoras
y bug-fixing por parte de miembros de la plantilla de Igalia.

4
2.3. Herramientas y entorno de trabajo 5

Con los años ha atravesado diversas versiones que tuvieron como resultado una am-
pliación constante de sus funcionalidades, además de la solución de los bugs que han ido
surgiendo. Por ello la aplicación que inicialmente tenı́a como único objetivo la anotación del
trabajo en base a un modelo muy sencillo fue adoptando entidades y capacidades nuevas.
El cálculo de horas extra, la clasificación de los clientes según su sector, el cálculo de las
horas de vacaciones o el cálculo de desviación de costes en los proyectos son algunas de los
múltiples añadidos que se han realizado a PhpReport desde su creación.
A pesar de la utilidad y potencial que ha demostrado en todos estos años, la aplicación
comienzar a presentar serios inconvenientes. En primer lugar, de cara al usuario presenta
unas interfaces web meramente funcionales, basadas totalmente en formularios estáticos.
A dı́a de hoy su interfaz ha quedado claramente desfasada al lado de otras aplicaciones
web con comportamientos dinámicos. Por otra parte, para los desarrolladores comienza a
convertirse en código insostenible debido a una barrera muy difusa entre la capa modelo
y la capa web, además de por los seis años de parches a intervalos regulares. Este código
con una capacidad de modularidad muy escasa supone un claro impedimento tanto para el
añadido de nuevas funcionalidades como para labores de bug-fixing.
Mejorar tanto la experiencia de los usuarios finales como el trabajo sobre el código de
futuros programadores, sean de Igalia o no, es el motivo para la confección de una nueva
versión de PhpReport, y por lo tanto de su ampliación abordada en este proyecto.

2.3. Herramientas y entorno de trabajo


2.3.1. Entorno informático básico de trabajo
El alumno empleó casi siempre para la realización del proyecto su ordenador portátil,
con las especificaciones:

• Procesador: Intel Core 2 Duo T5800 2 GHz


• Memoria RAM: 3’8 GB
• SO: Ubuntu 9.10 (Karmic)

Además en unas pocas ocasiones empleó el equipo de sobremesa de su puesto de trabajo


en la oficina de Igalia, con las siguientes caracterı́sticas:

• Procesador: Intel Pentium 4 2.26 GHz


• Memoria RAM: 741.3 MB
• SO: Ubuntu 9.04 (Jaunty)

2.3.2. Lenguajes, bibliotecas, modelos y enfoques empleados


El alumno desarrolló su trabajo con los siguientes lenguajes, bibliotecas, modelos y
sistemas de diversos tipos (descripciones extraı́das de la Wikipedia [2]).
2.3. Herramientas y entorno de trabajo 6

Programación orientada a objetos


Descripción [3]
La Programación Orientada a Objetos (POO) es un paradigma de programación que
usa objetos y sus interacciones para diseñar aplicaciones y programas de ordena-
dor. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo
y encapsulamiento. Su uso se popularizó a principios de la década de 1990. En la
actualidad existe una gran variedad de lenguajes de programación que soportan la
orientación a objetos.
Este paradigma se sustenta en los objetos, entidades que combinan estado (atributo),
comportamiento (método) e identidad:

• El estado está compuesto de datos, será uno o varios atributos a los que se
habrán asignado unos valores concretos (datos).
• El comportamiento está definido por los procedimientos o métodos con que
puede operar dicho objeto, es decir, qué operaciones se pueden realizar con él.
• La identidad es una propiedad de un objeto que lo diferencia del resto, dicho
con otras palabras, es su identificador (concepto análogo al de identificador de
una variable o una constante).

Métodos (comportamiento) y atributos (estado) están estrechamente relacionados


por la propiedad de conjunto. Esta propiedad destaca que una clase requiere de
métodos para poder tratar los atributos con los que cuenta. El programador debe
pensar indistintamente en ambos conceptos, sin separar ni darle mayor importancia a
alguno de ellos. Hacerlo podrı́a producir el hábito erróneo de crear clases contenedoras
de información por un lado y clases con métodos que manejen a las primeras por el
otro. De esta manera se estarı́a realizando una programación estructurada camuflada
en un lenguaje de programación orientado a objetos.
La POO difiere de la programación estructurada tradicional, en la que los datos y
los procedimientos están separados y sin relación, ya que lo único que se busca es el
procesamiento de unos datos de entrada para obtener otros de salida. La programación
estructurada anima al programador a pensar sobre todo en términos de procedimientos
o funciones, y en segundo lugar en las estructuras de datos que esos procedimientos
manejan. En la programación estructurada sólo se escriben funciones que procesan
datos. Los programadores que emplean POO, en cambio, primero definen objetos
para luego enviarles mensajes solicitándoles que realicen sus métodos por sı́ mismos.
Justificación
Se eligió prácticamente desde el primer momento la POO como paradigma de progra-
mación debido a que el sistema estarı́a más centrado en el manejo de contenedores
de datos mapeados a entidades de la Base de Datos (BD) que a la ejecución de algo-
ritmos o funciones. Además, el hecho de haber empleado este paradigma, aunque no
fuera de manera pura1 , en la versión anterior de PhpReport con resultados exitosos
demostró que resultaba una elección correcta.
1
PHP no era un lenguaje con soporte para orientación a objetos antes de su versión 5.
2.3. Herramientas y entorno de trabajo 7

Tecnologı́as analizadas y descartadas en su lugar

• Programación declarativa [4]


La Programación Declarativa es un paradigma de programación que está basa-
do en el desarrollo de programas especificando o ((declarando)) un conjunto de
condiciones, proposiciones, afirmaciones, restricciones, ecuaciones o transforma-
ciones que describen el problema y detallan su solución. La solución es obtenida
mediante mecanismos internos de control, sin especificar exactamente cómo en-
contrarla. No existen asignaciones destructivas, y las variables son utilizadas con
transparencia referencial.
En la programación declarativa las sentencias que se utilizan lo que hacen es
describir el problema que se quiere solucionar, pero no las instrucciones necesa-
rias para solucionarlo, al contrario que en el enfoque imperativo. Esto último se
realizará mediante mecanismos internos de inferencia de información a partir de
la descripción realizada.
Al no tratarse de un programa con un fuerte componente matemático o lógico, el
enfoque declarativo no presentaba verdaderas ventajas, ası́ que se descartó rápi-
damente.
• Programación funcional [5]
La Programación Funcional es un paradigma de programación declarativa basa-
do en la utilización de funciones aritméticas, cuyo objetivo es conseguir lenguajes
expresivos y matemáticamente elegantes, en los que no sea necesario bajar al
nivel de la máquina para describir el proceso llevado a cabo por el programa,
y evitando el concepto de estado del cómputo. La secuencia de computaciones
llevadas a cabo por el programa se regirı́a única y exclusivamente por la rees-
critura de definiciones más amplias a otras cada vez más concretas y definidas,
usando lo que se denominan ((definiciones dirigidas)).
Los programas escritos en un lenguaje funcional están constituidos únicamente
por definiciones de funciones, entendiendo éstas no como subprogramas clási-
cos de un lenguaje imperativo, sino como funciones puramente matemáticas,
en las que se verifican ciertas propiedades como la transparencia referencial (el
significado de una expresión depende únicamente del significado de sus subex-
presiones), y por tanto, la carencia total de efectos laterales.
Otras caracterı́sticas propias de estos lenguajes son la inexistencia de asignacio-
nes de variables y la falta de construcciones estructuradas como la secuencia o
la iteración (lo que obliga en la práctica a que todas las repeticiones de instruc-
ciones se lleven a cabo por medio de funciones recursivas).
De nuevo el resultar un sistema con un componente matemático poco complejo
motivó el rápido descarte de este paradigma.

PHP
Descripción [6, 7]
2.3. Herramientas y entorno de trabajo 8

Lenguaje de programación interpretado, diseñado originalmente para la creación de


páginas web dinámicas. Generalmente se ejecuta en un servidor web, tomando el
código en PHP Hypertext Preprocessor (PHP) como su entrada y creando páginas
web como salida, pero actualmente puede ser utilizado desde una interfaz de lı́nea
de comandos o en la creación de otros tipos de programas incluyendo aplicaciones
con interfaz gráfica usando las bibliotecas Qt o GTK+. El gran parecido que posee
PHP con los lenguajes más comunes de programación estructurada, como C y Perl,
permiten a la mayorı́a de los programadores crear aplicaciones complejas con una
curva de aprendizaje muy corta. También les permite involucrarse con aplicaciones de
contenido dinámico sin tener que aprender todo un nuevo grupo de funciones.
Puede ser desplegado en la mayorı́a de los servidores web y en casi todos los sistemas
operativos y plataformas sin coste alguno. PHP se encuentra actualmente instalado
en más de 20 millones de sitios web y en un millón de servidores, siendo también
el módulo Apache más popular entre las computadoras que utilizan Apache como
servidor web. La versión más reciente de PHP es la 5.3.2 del 04 de marzo de 2010.
PHP es un acrónimo recursivo que significa PHP Hypertext Pre-processor (inicialmen-
te PHP Tools, o, Personal Home Page Tools). Fue creado originalmente por Rasmus
Lerdorf en 1994; sin embargo la implementación principal de PHP es producida ahora
por The PHP Group y sirve como el estándar de facto para PHP al no haber una
especificación formal. Publicado bajo la PHP License, la Free Software Foundation
considera esta licencia como software libre.

Justificación
PHP fue percibido como el lenguaje idóneo para la realización del núcleo de la apli-
cación por presentar las siguientes caracterı́sticas:

• Soporte para una gran cantidad de bases de datos (MySQL, PostgreSQL, Ora-
cle...).
• Capacidades completas para POO desde su versión 5.
• Integración con multitud bibliotecas externas, dotándole de numerosas funcio-
nalidades, desde generar documentos en PDF hasta analizar código Extensible
Markup Language (XML).
• Sistema muy simple de creación de páginas web dinámicas mediante la ejecución
del código en el lado del servidor.
• Código notablemente más sencillo de mantener y extender gracias a su intuitiva
sintaxis y flexibilidad en el tipado.
• Siendo código abierto en su totalidad, PHP goza de la ayuda de un gran grupo
de programadores, permitiendo que los fallos de funcionamiento se encuentren
y reparen rápidamente.
• Diversas opciones para un control sencillo de la comunicación con el usuario en
el lado del servidor (manejo de sesiones, gestión de cookies, etc).

Tecnologı́as analizadas y descartadas en su lugar


2.3. Herramientas y entorno de trabajo 9

• Python[8, 9]
Python es un lenguaje de programación interpretado creado por Guido van Ros-
sum en el año 1991.
Se compara habitualmente con Tcl, Perl, Scheme, Java y Ruby. En la actualidad
Python se desarrolla como un proyecto de código abierto, administrado por la
Python Software Foundation. La última versión estable del lenguaje es la 3.1.1
Python permite dividir el programa en módulos reutilizables desde otros progra-
mas Python. Viene con una gran colección de módulos estándar que se pueden
utilizar como base de los programas (o como ejemplos para empezar a apren-
der Python). También hay módulos incluidos que proporcionan E/S de ficheros,
llamadas al sistema, sockets y hasta interfaces a GUI (interfaz gráfica con el
usuario) como Tk, GTK, Qt entre otros.
Python se utiliza como lenguaje de programación interpretado, lo que ahorra un
tiempo considerable en el desarrollo del programa, pues no es necesario compilar
ni enlazar. El intérprete se puede utilizar de modo interactivo, lo que facilita
experimentar con caracterı́sticas del lenguaje, escribir programas desechables o
probar funciones durante el desarrollo del programa.
El nombre del lenguaje proviene de la afición de su creador original, Guido van
Rossum, por los humoristas británicos Monty Python. El principal objetivo que
persigue este lenguaje es la facilidad, tanto de lectura como de diseño.
Entre sus otras caracterı́sticas podemos destacar:
◦ Soporte para los tres principales paradigmas de programación: orientada a
objetos, estructurada y funcional.
◦ Tipado dinámico.
◦ Resolución dinámica de nombres.
◦ Sintaxis más clara debido a su identación obligatoria.
◦ Soporte multiplataforma (consecuencia de ser un lenguaje interpretado).
◦ Facilidad de extensión mediante módulos en C o C++.
No hubo aspectos concretos de Python que motivaran su descarte, sino que
PHP se percibió como una opción más adecuada para nuestro propósito al estar
centrado en el desarrollo de aplicaciones web, con un gran número de librerı́as
y funciones sencillas para ello, especialmente en lo referente a páginas web
dinámicas.

PHPUnit
Descripción [10]
Framework de pruebas unitarias para PHP. Creado por Sebastian Bergmann, forma
parte de la familia de frameworks de pruebas xUnit. Actualmente es el framework
más empleado para la creación de pruebas en PHP, siendo algunas de sus principales
caracterı́sticas:
2.3. Herramientas y entorno de trabajo 10

• Forma parte del grupo de frameworks de xUnit


• Puerto completo deJUnit para PHP5.
• Soporte para Mock Objects (jMock).
• Almacena los resultados en una Test Database.
• Se integra con varias aplicaciones de test.

Justificación
Las pruebas unitarias de PHP fueron realizadas completamente con PHPUnit debido
a que es el framework de pruebas más completo y empleado en ese lenguaje.

JavaScript
Descripción [11, 12]
Lenguaje de scripting basado en objetos, utilizado para acceder a objetos en apli-
caciones. Principalmente, se utiliza integrado en un navegador web permitiendo el
desarrollo de interfaces de usuario mejoradas y páginas web dinámicas. JavaScript es
un dialecto de ECMAScript y se caracteriza por ser un lenguaje basado en prototi-
pos, con entrada dinámica y con funciones de primera clase. JavaScript ha tenido
influencia de múltiples lenguajes y se diseñó con una sintaxis similar al lenguaje de
programación Java, aunque más fácil de utilizar para personas que no programan.
Todos los navegadores modernos interpretan el código JavaScript integrado dentro de
las páginas web. Para interactuar con una página web se provee al lenguaje JavaScript
de una implementación del Document Object Model (DOM).
El lenguaje fue inventado por Brendan Eich en la empresa Netscape Communications,
la que desarrolló los primeros navegadores web comerciales. Apareció por primera vez
en el producto de Netscape llamado Netscape Navigator 2.0.
Tradicionalmente, se venı́a utilizando en páginas web HyperText Markup Langua-
ge (HTML), para realizar operaciones y en el marco de la aplicación cliente, sin
acceso a funciones del servidor. JavaScript se ejecuta en el agente de usuario, al
mismo tiempo que las sentencias van descargándose junto con el código HTML.

Justificación
La elección del framework ExtJS (apartado 2.3.2 en la página 12), el cual está cons-
truido mediante JavaScript, implicó el uso de este lenguaje para la realización de las
interfaces web.

AJAX
Descripción [13]
2.3. Herramientas y entorno de trabajo 11

Asynchronous JavaScript And XML (AJAX) es una técnica de desarrollo web para
crear aplicaciones dinámicas. Estas aplicaciones se ejecutan en el cliente, es decir,
en el navegador de los usuarios mientras se mantiene la comunicación ası́ncrona
con el servidor en segundo plano. De esta forma es posible realizar cambios sobre
las páginas sin necesidad de recargarlas, lo que significa aumentar la interactividad,
velocidad y usabilidad en las aplicaciones. Habitualmente se considera a AJAX como
el soporte para el tipo más sencillo de aplicaciones Rich Internet Applications (RIA),
aunque no debemos confundirlo con las verdaderas aplicaciones RIA, de mucha mayor
complejidad.
AJAX es una tecnologı́a ası́ncrona, en el sentido de que los datos adicionales se
requieren al servidor y se cargan en segundo plano sin interferir con la visualización
ni el comportamiento de la página. JavaScript es el lenguaje interpretado (scripting
language) en el que normalmente se efectúan las funciones de llamada de AJAX
mientras que el acceso a los datos se realiza mediante XMLHttpRequest, objeto
disponible en los navegadores actuales. En cualquier caso, no es necesario que el
contenido ası́ncrono esté formateado en XML.
AJAX es una técnica válida para múltiples plataformas y utilizable en muchos sis-
temas operativos y navegadores dado que está basado en estándares abiertos como
JavaScript y DOM.

Justificación
Las interfaces dinámicas creadas por el alumno siguen el enfoque AJAX en su inmensa
mayorı́a ya que es el enfoque de diseño web que nos permite delegar código en el
navegador del cliente y obtener interfaces dinámicas con su comunicación ası́ncrona
con el servidor (uno de los objetivos globales del proyecto).

Tecnologı́as analizadas y descartadas en su lugar

• RIA[14]
Las aplicaciones plenamente Rich Internet Applications (RIA) son aplicaciones
web que tienen la mayorı́a de las caracterı́sticas de las aplicaciones tradicionales.
Estas aplicaciones utilizan un navegador web especı́fico para ejecutarse, y por
medio de un plugin, o independientemente mediante una máquina virtual o un
sandbox, se agregan las caracterı́sticas adicionales.
Esta surge como una combinación de las ventajas que ofrecen las aplicaciones
Web y las aplicaciones tradicionales. Buscan mejorar la experiencia del usuario
Normalmente en las aplicaciones web hay una recarga continua de páginas cada
vez que el usuario pulsa sobre un enlace. De esta forma se produce un tráfico
muy alto entre el cliente y el servidor, llegando muchas veces a recargar la misma
página con un mı́nimo cambio.
En los entornos RIA, en cambio, no se producen recargas de página, ya que
desde el principio se carga toda la aplicación, y sólo se produce comunicación
con el servidor cuando se necesitan datos externos como datos de una BD o de
otros ficheros externos.
2.3. Herramientas y entorno de trabajo 12

No debemos confundir aplicaciones totalmente RIA con AJAX, ya que, aunque


los dos posibilitan la creación de aplicaciones web dinámicas, el primero requiere
un navegador especı́fico con el que añade caracterı́sticas adicionales a las pági-
nas, mientras que en AJAX la página se visualiza del modo tradicional pero
permitiendo la comunicación con el servidor sin necesidad de recargarla.
El enfoque RIA absoluto se descartó rápidamente debido a la gran complejidad
que añade sobre el diseño de páginas web tradicionales al requerir software es-
pecı́fico para su visualización, además de disponer por el momento de un número
bastante limitado de recursos y frameworks libres. AJAX, por el contrario, pre-
senta una mayor flexibilidad (cualquier navegador puede visualizar las páginas)
y un número muy elevado de recursos libres de todo tipo.

ExtJS
Descripción [15, 16]
Biblioteca de JavaScript para el desarrollo de aplicaciones web interactivas usando
tecnologı́as como AJAX, Dynamic HTML (DHTML) y DOM. Como casi todas las
interfaces, se basa en la programación dirigida por eventos.
Originalmente construida como una extensión de la biblioteca YUI, en la actualidad
puede usarse como extensión para las biblioteca jQuery y Prototype. Desde la versión
1.1 puede ejecutarse como una aplicación independiente.
Incluye un gran número de ((widgets)) y caracterı́sticas, como:

• Cuadros y áreas de texto • Árbol de datos


• Campos para fechas • Pestañas
• Campos numéricos • Tablas personalizables y ordenables
• Combos • Editores de tablas en lı́nea
• Radiobuttons • Manejo simple de múltiples ventanas
• Checkboxes • Etc.

Justificación
Se eligió la biblioteca ExtJS frente a otras por presentar un gran abanico de po-
sibilidades de personalización en un nivel superior, disponiendo además de un gran
número de ((widgets)) ya predefinidos y fácilmente configurables de diversos modos,
incluyendo tanto contenedores como elementos individuales o de comunicación (e.g.
proxy para XML), lo que facilitaba al programador la obtención de una interfaz de
alto nivel.

Tecnologı́as analizadas y descartadas en su lugar

• jQuery[17, 18]
2.3. Herramientas y entorno de trabajo 13

jQuery es una biblioteca o framework de Javascript, creada inicialmente por John


Resig, que permite simplificar la manera de interactuar con los documentos
HTML, manipular el arbol DOM, manejar eventos, desarrollar animaciones y
agregar interacción con la tecnologı́a AJAX a páginas web.
Entre sus caracterı́sticas podemos destacar:
◦ Selección de elementos DOM.
◦ Interactividad y modificaciones del árbol DOM, incluyendo soporte para
Cascading Style Sheets (CSS) 1-3 y un plugin básico de XPath.
◦ Soporte AJAX.
◦ Eventos.
◦ Manipulación de la hoja de estilos CSS.
◦ Efectos y animaciones.
◦ Soporte de extensiones.
Sobre los motivos de su descarte, no se le encontraron mayores problemas a
la librerı́a, sino que simplemente se consideró a ExtJS más adecuada para el
proyecto.
• Prototype[19, 20]
Framework escrito en JavaScript que se orienta al desarrollo sencillo y dinámico
de aplicaciones web. Es una herramienta basada en un único fichero (proto-
type.js) que implementa las técnicas AJAX y su potencial es aprovechado al
máximo cuando se desarrolla con Ruby On Rails.
Entre sus caracterı́sticas podemos destacar:
◦ Extenso Application Programming Interface (API) en JavaScript orientado
a AJAX.
◦ Librerı́as con soporte para clases y objetos.
◦ Soporte de prototipado en las funciones de creación de objetos.
Al igual que jQuery, el principal motivo para su descarte fue la preferencia por
ExtJS, aunque de por sı́ ya presentaba una API bastante más limitada que
jQuery.

PostgreSQL
Descripción [21, 22]
Sistema de gestión de base de datos relacional orientada a objetos de software libre,
publicado bajo la licencia Berkeley Software Distribution (BSD). Se trata de uno de
los sistemas de gestión de bases de datos más avanzados en la actualidad, entre cuyas
caracterı́sticas podemos destacar:

• Alta capacidad de concurrencia


• Amplia variedad de tipos nativos
2.3. Herramientas y entorno de trabajo 14

• Capacidad de ejecución de funciones en diversos lenguajes (C, R, PHP, Ruby,


C++, PL/PgSQL...)
• Múltiples opciones para la creación de disparadores
• Herencia de tablas
• Creación de vistas
• Soporte para transacciones distribuidas

Como muchos otros proyectos de código abierto, el desarrollo de PostgreSQL no es


manejado por una sola empresa sino que es dirigido por una comunidad de desa-
rrolladores y organizaciones comerciales las cuales trabajan en su desarrollo. Dicha
comunidad es denominada el PGDG (PostgreSQL Global Development Group).
PostgreSQL ha tenido una larga evolución, la cual se inicia en 1982 con el proyecto
Ingres en la Universidad de Berkeley. Este proyecto, liderado por Michael Stonebraker,
fue uno de los primeros intentos en implementar un motor de base de datos relacio-
nal. Después de haber trabajado un largo tiempo en Ingres y de haber tenido una
experiencia comercial con el mismo, Michael decidió volver a la Universidad en 1985
para trabajar en un nuevo proyecto sobre la experiencia de Ingres, dicho proyecto fue
llamado post-ingres o simplemente POSTGRES.

Justificación
PostgreSQL fue el sistema de gestión de bases de datos para el proyecto debido a que
presenta las siguientes ventajas frente a sus competidores:

• Eficiencia en el manejo de grandes volúmenes de datos.


• Facilidad para la creación de funciones personalizadas en casi cualquier lenguaje.
• Ejecución de múltiples instrucciones DDL en una única transacción, facilitando
la creación y actualización de la BD.
• Gran cantidad de diferentes tipos de datos, permitiendo su gestión de manera
más eficaz.

Tecnologı́as analizadas y descartadas en su lugar

• MySQL[8, 9]
MySQL es un sistema de gestión de base de datos relacional, multihilo y mul-
tiusuario con más de seis millones de instalaciones. MySQL AB (desde enero de
2008 una subsidiaria de Sun Microsystems y ésta a su vez de Oracle Corporation
desde abril de 2009) desarrolla MySQL como software libre en un esquema de
licenciamiento dual.
Por un lado se ofrece bajo la GPL para cualquier uso compatible con esta licencia,
pero para aquellas empresas que quieran incorporarlo en productos privativos
deben comprar a la empresa una licencia especı́fica que les permita este uso.
Está desarrollado en su mayor parte en ANSI C.
Entre sus caracterı́sticas actuales (versión 5.1.46) encontramos:
2.3. Herramientas y entorno de trabajo 15

◦ Procedimientos almacenados.
◦ Cursores.
◦ Vistas actualizables.
◦ Modo Strict.
◦ Motores de almacenamiento independientes.
◦ Caché de queries.
◦ Selects anidados.
◦ Soporte para Secure Socket Layer (SSL).
No presentó motivos propios para descartarla, sino que se prefirió PostgreSQL
debido a sus optimizaciones para manejo de grandes volúmenes de datos (ciertos
cálculos requieren la extracción de un gran número de tareas) y a su mayor
abanico de tipos de datos (lo cual permite el empleo de un gran número de
funciones especı́ficas que permiten obtener datos calculados en las queries).

Apache
Descripción [23, 24]
Servidor web HyperText Transfer Protocol (HTTP) de código abierto para platafor-
mas Unix (BSD, GNU/Linux, etc.), Windows, Macintosh y otras, que implementa el
protocolo HTTP/1.1 y la noción de sitio virtual. Cuando comenzó su desarrollo en
1995 se basó inicialmente en código del popular NCSA HTTPd 1.3, pero más tarde
fue reescrito por completo. Su nombre se debe a que Behelendorf eligió ese nombre
porque querı́a que tuviese la connotación de algo que es firme y enérgico pero no
agresivo, y la tribu Apache fue la última en rendirse al que pronto se convertirı́a en
gobierno de EEUU, y en esos momentos la preocupación de su grupo era que llegasen
las empresas y ((civilizasen)) el paisaje que habı́an creado los primeros ingenieros de
internet. Además Apache consistı́a solamente en un conjunto de parches a aplicar al
servidor de NCSA. Era, en inglés, a patchy server (un servidor ((parcheado))).
Apache presenta entre otras caracterı́sticas altamente configurables, bases de datos
de autenticación y negociado de contenido, pero fue criticado por la falta de una
interfaz gráfica que ayude en su configuración.
Es usado primariamente para enviar páginas web estáticas y dinámicas en la World
Wide Web. Muchas aplicaciones web están diseñadas asumiendo como ambiente de
implantación a Apache, o que utilizarán caracterı́sticas propias de este servidor web.
Apache es el componente de servidor web en la popular plataforma de aplicaciones
LAMP, junto a MySQL y los lenguajes de programación PHP/Perl/Python (y ahora
también Ruby).
La licencia de software bajo la cual el software de la fundación Apache es distribuido
es una parte distintiva de la historia de Apache HTTP Server y de la comunidad de
código abierto. La Licencia Apache permite la distribución de derivados de código
abierto y cerrado a partir de su código fuente original.
2.3. Herramientas y entorno de trabajo 16

La Free Software Foundation no considera a la Licencia Apache como compatible con


la versión 2 de la GNU General Public License (GPL), en la cual el software licenciado
bajo la Apache License no puede ser integrado con software distribuido bajo la GPL,
Sin embargo, la versión 3 de la GPL incluye una provisión (Sección 7e) que le permite
ser compatible con licencias que tienen cláusulas de represalia de patentes, incluyendo
a la Licencia Apache.

Justificación
Apache es el servidor web libre más popular en la actualidad, con una calidad probada
a lo largo de los años y una gran cantidad de módulos para aumentar o mejorar su
funcionamiento, lo cual hizo que fuera directamente el elegido para probar todas las
páginas web.

XML
Descripción [25, 26]
Siglas en inglés de Extensible Markup Language (lenguaje de marcas extensible), es
un metalenguaje extensible de etiquetas desarrollado por el World Wide Web Con-
sortium (W3C). Es una simplificación y adaptación del Standard Generalized Mark-
up Language (SGML) y permite definir la gramática de lenguajes especı́ficos (de
la misma manera que HTML es a su vez un lenguaje definido por SGML). Por lo
tanto XML no es realmente un lenguaje en particular, sino una manera de definir
lenguajes para diferentes necesidades. Algunos de estos lenguajes que usan XML para
su definición son Extensible HyperText Markup Language (XHTML), Scalable Vector
Graphics (SVG), Mathematical Markup Language (MathML).
El formato XML no nació sólo para su aplicación en Internet, sino que se propone
como un estándar para el intercambio de información estructurada entre diferentes
plataformas. Se puede usar en bases de datos, editores de texto, hojas de cálculo y
casi cualquier cosa imaginable.
Su amplia extensión se debe en gran parte a que es una tecnologı́a sencilla que tiene
a su alrededor otras que la complementan y la hacen mucho más grande y con unas
posibilidades mucho mayores. Tiene un papel muy importante en la actualidad ya
que permite la compatibilidad entre sistemas para compartir la información de una
manera segura, fiable y fácil.

Justificación
XML fue empleado en el proyecto como principal lenguaje para intercambio de infor-
mación entre sistemas por el simple motivo de ser el más extendido en la actualidad,
prácticamente considerado un estándar de facto (con soporte del W3C), y por tanto
el idóneo para lograr la comunicación de la aplicación con otras externas.
En los comienzos de la era internet XML logró su aceptación gracias, entre otras
caracterı́sticas, a que su similitud con HTML facilitó la reutilización de tecnologı́a ya
existente para este último.
2.3. Herramientas y entorno de trabajo 17

JSON
Descripción [27, 28]
JavaScript Object Notation (JSON) es un formato ligero para el intercambio de datos,
subconjunto de la notación literal de objetos de JavaScript que no requiere el uso de
XML.
La simplicidad de JSON ha dado lugar a la generalización de su uso, especialmente
como alternativa a XML en AJAX. Una de las ventajas de JSON sobre XML como
formato de intercambio de datos en este contexto es que es mucho más sencillo
escribir un analizador semántico de JSON. En JavaScript, JSON puede ser analizado
trivialmente usando el procedimiento eval(), lo cual ha sido fundamental para la
aceptación de JSON por parte de la comunidad de desarrolladores AJAX, debido a la
ubicuidad de JavaScript en casi cualquier navegador web.
JSON se emplea habitualmente en entornos donde el tamaño del flujo de datos entre
cliente y servidor es de vital importancia (de aquı́ su uso por Yahoo, Google, etc, que
atienden a millones de usuarios) cuando la fuente de datos es explı́citamente de fiar
y donde no es importante el no disponer de procesamiento XSLT para manipular los
datos en el cliente.

Justificación
ExtJS incluye métodos de parseo y captura de datos de JSON más potentes que los de
XML para los ((widgets)) AJAX más complejos, y por ello se empleó como lenguaje de
intercambio de información en casos concretos, a fin de aprovechar dichas ventajas.

HTML
Descripción [29, 30]
HyperText Markup Language (HTML) es el lenguaje de marcado predominante para
la construcción de páginas web. Es usado para describir la estructura y el contenido
en forma de texto, ası́ como para complementar el texto con objetos tales como
imágenes. HTML se escribe en forma de ((etiquetas)), rodeadas por corchetes angulares
(<, >). HTML también puede describir, hasta un cierto punto, la apariencia de un
documento, y puede incluir un script (por ejemplo Javascript), el cual puede afectar
el comportamiento de navegadores web y otros procesadores de HTML.
HTML también es usado para referirse al contenido del tipo de MIME text/html
o todavı́a más ampliamente como un término genérico para el HTML, ya sea en
forma descendida del XML (como XHTML 1.0 y posteriores) o en forma descendida
directamente de SGML (como HTML 4.01 y anteriores).

Justificación
2.3. Herramientas y entorno de trabajo 18

En las páginas web de cualquier tipo se empleó HTML para su realización (directa
o indirectamente), por el simple hecho de ser el lenguaje de marcado estándar en
tecnologı́as web.

Selenium
Descripción [31, 32]
Selenium es un framework para testeo de aplicaciones web. Proporciona una herra-
mienta de registro y reproducción de acciones que permite crear tests sin necesidad
de emplear explı́citamente un lenguaje de scripting. Selenium proporiona un Domain
Specific Language (DSL) para la escritura de tests formales (pero no unitarios) en di-
versos de los más populares lenguajes de programación (Java, Ruby, Python, PHP...).
La reproducción de los tests es posible en la mayorı́a de los navegadores web moder-
nos. Selenium funciona en plataformas Windows, Linux y Macintosh.
Selenium incluye un Integrated Development Environment (IDE) implementado como
extensión de Firefox que permite grabar, editar y reproducir tests (con capacidades
de debugging). Incluye las siguientes caracterı́sticas:

• Grabación y reproducción de tests.


• Selección inteligente de campos empleando su ID, nombre o XPath según sea
necesario.
• Autocompleción para todos los comandos comunes de Selenium.
• Tests de Walkthrough.
• Inserción de puntos de ruptura.
• Diversos formatos de guardado, como HTML, Ruby o PHP.
• Soporte para extensiones personalizadas.
• Opción para comprobar automáticamente el tı́tulo de cada página.

Justificación
Selenium fue el framework escogido para realizar las pruebas sobre las interfaces web
debido a su facilidad de uso, tanto a la hora de escribir las pruebas como de ejecutarlas,
a la gran variedad de comandos que permite ejecutar (incluyendo algunos de cierta
complejidad, como ((drag & drop))), sus opciones de debugging y a su capacidad de
registrar las acciones realizadas por el usuario, lo que permite una escritura rápida de
los tests.

UML
Descripción [33, 34]
2.3. Herramientas y entorno de trabajo 19

Lenguaje Unificado de Modelado (UML, por sus siglas en inglés, Unified Modeling
Language) es el lenguaje de modelado de sistemas de software más conocido y utili-
zado en la actualidad; está respaldado por el OMG (Object Management Group). Es
un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema.
UML ofrece un estándar para describir un ((plano)) del sistema (modelo), incluyendo
aspectos conceptuales tales como procesos de negocio y funciones del sistema, y as-
pectos concretos como expresiones de lenguajes de programación, esquemas de bases
de datos y componentes reutilizables.
Es importante resaltar que UML es un ((lenguaje de modelado)) para especificar o
para describir métodos o procesos. Se utiliza para definir un sistema, para detallar
los artefactos en el sistema y para documentar y construir. En otras palabras, es el
lenguaje en el que está descrito el modelo.
Se puede aplicar en el desarrollo de software entregando gran variedad de formas
para dar soporte a una metodologı́a de desarrollo de software (tal como el Proceso
Unificado Racional o RUP), pero no especifica en sı́ mismo qué metodologı́a o proceso
usar.
Justificación
Tanto los diagramas incluidos en esta memoria propios de la fase de diseño como
los de la BD empleados como entrada del programa tedia2sql (comentado en el
apartado 2.3.3 en la página siguiente) durante la implementación se realizaron como
diagramas UML por ser éste el lenguaje de modelado más conocido, extendido y
trabajado hoy en dı́a, existiendo además múltiples herramientas software para su
manejo.

E-R
Descripción [35, 36]
Un diagrama o modelo entidad-relación (a veces denominado por su siglas E-R,
((Entity relationship)), o DER, ((Diagrama de Entidad Relación))) es una herramienta
para el modelado de datos de un sistema de información. Estos modelos expresan en-
tidades relevantes para un sistema de información, sus inter-relaciones y propiedades.
El modelo Entidad-Relación es un concepto de modelado para bases de datos, pro-
puesto por Peter Chen en 1976, mediante el cual se pretende ‘visualizar’ los objetos
que pertenecen a la BD como entidades (se corresponde al concepto de objeto de
la Programación Orientada a Objetos) las cuales tienen unos atributos y se vinculan
mediante relaciones.
Es una representación conceptual de la información. Mediante una serie de procedi-
mientos se puede pasar del modelo E-R a otros, como por ejemplo el modelo relacional.
Justificación
El modelo Entidad Relación es el modelo por excelencia para la creación de bases
de datos, con probada eficacia durante más de tres décadas durante las cuales se ha
2.3. Herramientas y entorno de trabajo 20

mejorado de diversos modos, haciéndolo la mejor opción para crear los diagramas de
diseño de la base de datos.

Modelo relacional
Descripción [37]
El modelo relacional para la gestión de una BD es un modelo de datos basado en
la lógica de predicados y en la teorı́a de conjuntos. Es el modelo más utilizado en la
actualidad para modelar problemas reales y administrar datos dinámicamente. Tras
ser postuladas sus bases en 1970 por Edgar Frank Codd, de los laboratorios IBM
en San José (California), no tardó en consolidarse como un nuevo paradigma en los
modelos de base de datos.
Su idea fundamental es el uso de ((relaciones)). Estas relaciones podrı́an considerarse
en forma lógica como conjuntos de datos llamados ((tuplas)). Pese a que ésta es la
teorı́a de las bases de datos relacionales creadas por Edgar Frank Codd, la mayorı́a
de las veces se conceptualiza de una manera más fácil de imaginar, esto es, pensando
en cada relación como si fuese una tabla que está compuesta por registros (cada fila
de la tabla serı́a un registro o tupla), y columnas (también llamadas campos).

Justificación
Aunque no se crearon manualmente las tablas de base de datos (se empleó la herra-
mienta tedia2sql, apartado 2.3.3), éstas se basan en el modelo relacional, el cual
permite mapear los diagramas Entidad Relación a la estructura de tablas de una BD,
por lo que su uso era necesario para pasar del modelo a la ‘implementación’.

2.3.3. Herramientas software empleadas


A lo largo de su trabajo el alumno empleó para fines concretos diversas herramientas
software que comentaremos a continuación.
2.3. Herramientas y entorno de trabajo 21

Nombre Descripción Apartado


OpenSSH [38] Conjunto de aplicaciones que permiten rea- Uso general
lizar comunicaciones cifradas a través de
una red, usando el protocolo SSH.
emacs [39] Editor de texto del proyecto GNU con una Uso general
gran cantidad de funciones, muy popular
entre programadores y usuarios técnicos.
vim [40] Versión mejorada del editor de texto vi, un Uso general
editor que se encuentra en (casi) todo sis-
tema de tipo Unix.
git [41] VCS muy versátil y extendido en el entorno Uso general
de desarrollo de Linux.
meld [42] Herramienta para comprobar las diferen- Uso general
cias entre dos archivos.
psql [22] Herramienta para el manejo de bases de da- Tareas de BD
tos en PostgreSQL por lı́nea de comando.
pgAdmin III Herramienta para el manejo de bases de da- Tareas de BD
[43] tos en PostgreSQL con interfaz de venta-
nas.
dia [44] Editor de diagramas de diversos tipos, co- Dise~
no
mo E-R o UML.
tedia2sql [45] Programa para crear el script de creación Creación BD
de una BD a partir de un diagrama UML
que la representa.
phpDocumentor Programa para crear la documentación de Documentación
[46] código PHP en base a una sintaxis sencilla
de los comentarios.
trac [47, 48] Sistema de seguimiento de problemas y me- Pruebas web
joras de proyectos software con un wiki in-
tegrado.
texmaker [49] Entorno de edición de LATEX, empleado pa- Memoria
ra la confección de este documento.

Tabla 2.1: herramientas software empleadas


2.4. Metodologı́a de trabajo 22

2.3.4. Herramientas software testeadas


Aquı́ comentaremos las herramientas software que el alumno analizó y probó pero que
finalmente no empleó por algún motivo.

Nombre Descripción Problemas Apartado


eclipse Entorno de desarrollo avan- No se logró que funciona- Uso general
[50] zado con soporte para PHP. ra correctamente con las
versiones más recientes de
PHP.
doxygen Sistema de documentación Simplemente se descu- Documentación
[51] con soporte para múltiples brió phpDocumentor, con
lenguajes. mayores funcionalidades al
estar centrado en PHP.

Tabla 2.2: herramientas software testeadas

2.4. Metodologı́a de trabajo


2.4.1. Descripción
La metodologı́a de trabajo empleada en Igalia es la llamada Extreme Programming (XP),
la cual es un enfoque de la ingenierı́a de software formulado por Kent Beck, autor del primer
libro sobre la materia, Extreme Programming Explained: Embrace Change [52]. Es el más
destacado de los procesos ágiles de desarrollo de software, habiendo tenido un importante
éxito en numerosas y muy diversas empresas de todo el mundo.
Al igual que los demás procesos ágiles de desarrollo software, la programación extrema
se diferencia de las metodologı́as tradicionales principalmente en que pone más énfasis en la
adaptabilidad que en la previsibilidad. Los defensores de XP consideran que los cambios de
requisitos sobre la marcha son un aspecto natural, inevitable e incluso deseable del desarrollo
de proyectos. Creen que ser capaz de adaptarse a los cambios de requisitos en cualquier
punto de la vida del proyecto es una aproximación mejor y más realista que intentar definir
todos los requisitos al comienzo del proyecto e invertir esfuerzos después en controlar los
cambios en los requisitos. Por ello los clientes se consideran también compañeros en el
equipo de desarrollo, verdadero núcleo de la metodologı́a. Este enfoque se basa en que
unas relaciones óptimas dentro del equipo de desarrollo facilitan la solución de los problemas
previstos por la propia metodologı́a XP.
Estas caracterı́sticas de la programación extrema permiten resumir su filosofı́a como la
adopción dinámica de las mejores metodologı́as de desarrollo de acuerdo a lo requerido por
el proyecto en cada una de sus etapas.
Esta filosofı́a dinámica funciona gracias a su énfasis en principios centrados en un trabajo
dinámico en equipo: simplicidad, comunicación, retroalimentación y coraje. Un quinto
principio, respeto, fue añadido en la segunda edición de Extreme Programming Explained
[53].
2.4. Metodologı́a de trabajo 23

Figura 2.1: funcionamiento básico de las metodologı́as de desarrollo ágiles

2.4.2. Caracterı́sticas
Las caracterı́sticas fundamentales de la metodologı́a son:

Desarrollo iterativo e incremental: pequeñas mejoras, unas tras otras.

Pruebas unitarias continuas, frecuentemente repetidas y automatizadas, incluyendo


pruebas de regresión. Se aconseja escribir el código de la prueba antes de la codifica-
ción. Véase, por ejemplo, las herramientas de prueba JUnit orientada a Java, PHPUnit
orientada a PHP y NUnit para la plataforma.NET. Estas dos últimas están inspira-
das en JUnit, probablemente la herramienta de asistencia para creación de pruebas
unitarias más popular en el mundo de la informática en la actualidad.

Programación en parejas: se recomienda que las tareas de desarrollo se lleven a


cabo por dos personas en un mismo puesto. Se supone que la mayor calidad del
código escrito de esta manera -el código es revisado y discutido mientras se escribe-
es más importante que la posible pérdida de productividad inmediata.

Frecuente integración del equipo de programación con el cliente o usuario. Se


recomienda que un representante del cliente trabaje junto al equipo de desarrollo.

Corrección de todos los errores antes de añadir nueva funcionalidad. Hacer entregas
frecuentes.

Refactorización del código, es decir, reescribir ciertas partes del código para au-
mentar su legibilidad y mantenibilidad pero sin modificar su comportamiento. Las
pruebas han de garantizar que en la refactorización no se ha introducido ningún fallo.

Propiedad del código compartida: en vez de dividir la responsabilidad en el desa-


rrollo de cada módulo en grupos de trabajo distintos, este método promueve el que
2.4. Metodologı́a de trabajo 24

todo el personal pueda corregir y extender cualquier parte del proyecto. Las frecuentes
pruebas de regresión garantizan que los posibles errores serán detectados.
Simplicidad en el código: es la mejor manera de que las cosas funcionen. Cuando
todo funcione se podrá añadir funcionalidad si es necesario. La programación extrema
apuesta que es más sencillo hacer algo simple y tener un poco de trabajo extra para
cambiarlo si se requiere, que realizar algo complicado y quizás nunca utilizarlo.
La causa de su enfoque centrado en simplicidad y comunicación es que ambas son
extraordinariamente complementarias. Con más comunicación resulta más fácil identificar
qué se debe y qué no se debe hacer. Cuanto más simple es el sistema, menos tendrá que
comunicar sobre éste, lo que lleva a una comunicación más completa, especialmente si se
puede reducir el equipo de programadores.

2.4.3. Aplicación
La programación extrema se aplicó durante la realización del proyecto mediante los
siguientes elementos:
Planificaciones semanales: cada semana se preparaba el trabajo de la semana si-
guiente (cada tarea a realizar tenı́a asociado un número de horas previstas).
Reuniones semanales: el alumno presentaba a su director como mı́nimo una vez a
la semana el trabajo realizado para discutir ambos el rumbo a tomar a continuación,
qué aspectos mejorar o corregir, las decisiones de diseño o implementación, etc. En
algunas ocasiones se pidió la opinión o consejo a otros miembros de la empresa, bien
como usuarios de la aplicación o como desarrolladores con experiencia en la realización
de aplicaciones web.
Anotación de horas trabajadas: se anotaban cada dı́a las horas trabajadas en las
distintas tareas planificadas, empleando para ello la versión existente de la aplicación
PhpReport. Cada entrada con las horas trabajadas incluı́a la hora de inicio, la de fin,
el tipo de tarea realizada (implementación, diseño, documentación...) y una breve
descripción. De este modo se disponı́a de una referencia con información inmediata
sobre el trabajo realizado, permitiendo la consulta por parte de cualquier implicado
en el proyecto y el seguimiento de la planificación semanal.
Seguimiento de la evolución del proyecto: realizado mediante la utilidad tWiki
[54] con la extensión XPTracker [55], para realizar el seguimiento del proyecto con las
caracterı́sticas del ciclo XP. En esta utilidad se anotaron las horas trabajadas (desde un
punto de vista general y no estrictatemente diario), las decisiones tomadas en cuanto
a diseño o implementación, aspectos complejos y/o interesantes de la aplicación para
otros programadores (e.g. explicación del funcionamiento de fragmentos de código
poco intuitivos) y los principales problemas encontrados (aquéllos que supusieron un
retraso respecto a lo inicialmente previsto). Todos estos datos sobre su planificación,
diseño e implementación lo convierten en una fuente de información esencial sobre el
proyecto, tanto para el propio alumno y el director como para otros programadores
que decidan emplear, modificar o estudiar el código realizado.
Capı́tulo 3

Estado del arte

Desde que el ordenador comenzó a irrumpir en los entornos de trabajo como una plata-
forma de propósito múltiple, dejando atrás sus años de herramienta para tareas especı́ficas,
los usuarios han intentado sacarle todo el provecho. De esta manera se han ido delegando en
él aspectos laborales de los que antes se ocupaban otros utensilios o personas. Si hoy parece
que la telefonı́a sobre IP acabará desterrando en más de una empresa a la telefonı́a tradi-
cional [56], la agenda con las horas trabajadas y la máquina de fichar ya fueron derrotadas
hace bastantes años por las aplicaciones de seguimiento y monitorización de actividades.
A principios de los 90 la popularización de los entornos de ventanas propició que las
empresas comenzaran a emplear de manera más generalizada los ordenadores como herra-
mienta central [57]. En aquella época se pudieron ver los primeros intentos de anotación
del trabajo realizado, que consistı́an en una simple agenda con un campo de texto por dı́a,
un simple émulo de la agenda tradicional [58]. Poco a poco se le comenzaron a añadir
campos adicionales que hacı́an más sencillo extraer información de ella, los cuales ahora ya
nos parecen totalmente esenciales en cualquier herramienta de este tipo, como el proyecto
al que pertenece la tarea o las horas de inicio y fin [59]. Prácticamente la totalidad de
estas herramientas eran de software privativo (GNU is Not Unix (GNU)/Linux aún no habı́a
alcanzado su etapa de popularidad [60]), y además funcionaban únicamente en local, por
lo que su función era únicamente para anotación personal del trabajo realizado, y si se
requerı́a sincronizarlo con otra fuente se debı́a hacer manualmente [58].
En los años 96 y 97 el comienzo de la era de internet significó un empuje crucial para
estas herramientas [61] [62]. Este mismo hecho supuso también el arranque definitivo del
software libre en casi todas las áreas [63], incluido el seguimiento de tareas, por lo que
a partir de este momento sı́ podemos hacer una distinción lógica entre las aplicaciones
privativas y las libres.

3.1. Evolución de las aplicaciones privativas


Las aplicaciones de pago, que ya habı́an dominado este sector en años anteriores, si-
guieron haciéndolo tras la popularización de internet. El motivo seguı́a siendo el mismo,
el uso extendido de Windows en los entornos ofimáticos empleados en la mayorı́a de las
empresas [60].
A continuación se abordarán los principales avances y modificaciones vividos por estas
herramientas.

25
3.1. Evolución de las aplicaciones privativas 26

3.1.1. Coordinación de múltiples fuentes


Internet no sólo permitió el crecimiento de estas herramientas, sino que la filosofı́a de la
creación de múltiples intranets en las empresas añadió un componente nuevo a su mecánica:
la centralización, o coordinación, de la información almacenada. De este modo la aplicación
no sólo era útil por sı́ sola en el ámbito personal, sino también en el empresarial, permitiendo
la contabilización del trabajo realizado [59].
La coordinación de la información almacenada se ha venido realizando principalmente
en base a los dos enfoques siguientes.

Exportación/importación de datos
Las aplicaciones seguı́an funcionando a nivel local, de manera que cada usuario las
seguı́a empleando del mismo modo que antes. La diferencia es que las aplicaciones incluı́an
una nueva funcionalidad: importación y exportación de datos. Esto les permitı́a guardar
la información en un formato especı́fico (normalmente con una sintaxis propia) para que
posteriormente pudiera ser parseado por la misma herramienta y recuperar los datos. Los
formatos más empleados hasta dı́a de hoy con este propósito han sido los lenguajes de
marcado, como XML, HTML y JSON, y las hojas de cálculo, principalmente Excel [64]
[59].
Gracias a esta opción existı́a la posibilidad de transferir datos locales de una máquina
a otra para mantener una central con todos ellos. La dinámica habitual era realizar regu-
larmente (una vez al dı́a la mayorı́a de las veces) una exportación de datos desde cada
máquina local, enviar los datos a la máquina central e importarlos en esta última. Una posi-
ble variante serı́a mantener todas las copias actualizadas con todos los datos, pero rara vez
se ha empleado este modelo. En cualquier caso, este proceso acababa siendo automatizado
mediante un script debido a lo mecánico que resulta, para que de ese modo fuera todavı́a
más transparente para los usuarios finales.
El principal problema de este enfoque es que los datos se encuentran desactualizados
la mayor parte del tiempo, hasta que se exportan los nuevos a la máquina central. Tam-
bién puede haber problemas con la modificación de datos anteriores si se ha optado por
exportaciones incrementales.

Almacenamiento centralizado
El enfoque de sincronización mediante exportación de datos presentaba el problema de
contener datos desactualizados la mayor parte del tiempo, y además el propio proceso de
exportar e importar resultaba molesto al suponer una carga de trabajo adicional. Esto llevó a
que de manera natural se pasara directamente a almacenar los datos de manera remota en
esa máquina central que los contenı́a todos, para de ese modo eliminar los dos problemas
mencionados [65].
Este enfoque produjo otros cambios relacionados con la gestión de intranets en em-
presas al basarse claramente en este enfoque. En primer lugar era evidente que además de
la instalación en local se necesitaba tener configurada correctamente la máquina remota
destinada a almacenar la información, ası́ como una conexión estable hasta ella desde to-
dos los hosts en los que los usuarios almacenarı́an información, y posteriormente se debı́a
3.1. Evolución de las aplicaciones privativas 27

configurar la aplicación en base a ello.


Un cambio todavı́a más importante fue el hecho de que al trabajar en remoto la gente
tenı́a en principio acceso a toda la información almacenada. Esto añadió los conceptos de
autenticación y autorización a la identificación que ya era inherente a la anotación de trabajo
(las horas anotadas se asignaban a un usuario de la empresa, aunque fuera de manera local).
A partir de entonces los usuarios se debı́an autenticar, bien a nivel de aplicación si ésta lo
soportaba, o bien a nivel de conexión, para poder acceder a esa información almacenada.
Una vez autenticados es posible filtrar su acceso a la información y sus privilegios sobre ella
según el usuario del que se trate [59].
No tardaron mucho en introducirse los roles con el objetivo de hacer más sencilla la
gestión de la autorización en la aplicación [59] [66]. Los roles, como en todos los demás
tipos de aplicaciones que los incluyen, permiten manejar conjuntos predefinidos de permisos
y aplicárselos a un grupo de usuarios de manera sencilla. Habitualmente se manejan los
roles de administrador y usuario, siendo el primero el encargado de visualizar y supervisar
el conjunto de la información y el segundo el que únicamente introduce y maneja sus datos
de trabajo personal. También es corriente ver roles intermedios, como por ejemplo el jefe
de proyecto que puede extraer información adicional de los proyectos que supervisa. Otro
posible enfoque para este apartado, dependiente ya de la polı́tica de la empresa, es la total
transparencia, por la cual todos los usuarios pueden ver toda la información almacenada
aunque sólo puedan modificar lo relativo a su trabajo.

3.1.2. Extracción de informes y minerı́a de datos


El almacenamiento coordinado de toda la información tenı́a como objetivo que la ex-
tracción de diferentes conjuntos de datos fuera lo más sencilla y automatizada posible,
normalmente con el objetivo de obtener información derivada a partir de ellos. Los informes
estadı́sticos, de resultados y de evolución han cobrado mayor importancia en las empresas
con el paso de los años debido a la facilidad con la que transmiten importantes conjuntos
de datos. Por ello la extracción de datos se ha convertido en un pilar de estas aplicaciones
una vez que la centralización se volvió una caracterı́stica ya asentada [59] [67] [68].
Los informes son una de las caracterı́sticas más útiles para los administradores de una
empresa, y también en bastantes casos para los usuarios, proporcionándoles diferentes visio-
nes de los datos almacenados en cuanto a completitud y amplitud. Aunque cada empresa
suele basarse en los que mejor se adecúan a su modelo de negocio, existen algunas carac-
terı́sticas comunes a muchos de ellos. Podemos encontrar los informes económicos (ingresos,
gastos, beneficios...) según departamento, empleado, proyecto, etc.; de horas trabajadas
para los usuarios en los diferentes proyectos; de progresión en los proyectos activos; de
evolución del coste por hora de los empleados...
Con el tiempo se ha ampliado el número de informes generados por defecto por las
diferentes aplicaciones, y además se les han incluido un número cada vez mayor de campos
para filtrar los datos a considerar, como fecha de inicio o fin, barreras en el porcentaje de
progresión de los proyectos, departamentos incluidos, etc. También se les han incorporado
gráficas en muchos de ellos a fin de hacer más visual e inmediata toda la información
detallada.
Las capacidades de minerı́a de datos, en las cuales se apoyan internamente las aplicacio-
3.1. Evolución de las aplicaciones privativas 28

nes para generar sus informes, también son incluidas en muchos casos para su uso directo
por parte del usuario, permitiéndole extraer la información de una manera más directa. Su
funcionamiento y sintaxis (en base simplemente a campos o no) se suele asemejar mucho
al de una interfaz gráfica simplificada para bases de datos, mostrando posteriormente las
filas extraı́das en una o varias tablas.
Este apartado ha aumentado mucho de importancia en los últimos años debido a la
mayor necesidad de informes que permitan seguir las lógicas de negocio cada vez más
complejas de las empresas. Esto provoca que la minerı́a de datos pueda ser determinante a
la hora de decantarse por una herramienta u otra en entornos empresariales mı́nimamente
grandes.

3.1.3. Integración en el entorno empresarial


En muchas empresas la información almacenada en estas herramientas ha crecido enor-
memente, yendo mucho más allá de la simple anotación de horas de trabajo, almacenando
también otros conjuntos de datos. Tanto esto como la mejora de las intranets de las empre-
sas han permitido su integración o comunicación con muchas otras aplicaciones empleadas
en su mismo entorno, facilitando el tránsito de información o incluso la automatización de
tareas [58].
Aunque algunas aplicaciones ofrecen desde hace años capacidades de integración con
otras herramientas, como Outlook o Excel, en la mayorı́a de los casos se necesitan configu-
raciones personalizadas. Esto implica la creación o modificación de código especı́fico para
cada caso o el empleo de un formato intermedio estándar (habitualmente de los comentados
para la exportación en el apartado 3.1.1 en la página 26).
Las caracterı́sticas y lógicas de negocio de la empresa son esenciales para la existencia
o no de este apartado, cuestiones como una fuerte supervisión o no de las actividades o
si se puede confiar completamente en la información almacenada en la aplicación. Algunos
ejemplos de integración con otras aplicaciones los podemos encontrar en la generación
automática de facturas a los clientes en base al número de horas trabajadas en sus proyectos,
el pago a las cuentas de los empleados según el trabajo realizado durante el mes o el
seguimiento de la evolución de un proyecto en un software de planificación.

3.1.4. Temporizador
Un problema que presentaban las aplicaciones de anotación de trabajo es que en muchas
ocasiones ni el propio usuario recordaba cuánto tiempo llevaba trabajando. Con el objetivo
de eliminar este problema muchas aplicaciones incluyeron un ((widget)) muy sencillo consis-
tente en un cronómetro que al pulsar un botón comenzará a contar el tiempo transcurrido,
permitiéndonos llevar cuenta de la duración de la actividad [59] [69]. Normalmente permi-
ten la introducción al comienzo de un nombre para la tarea, y muchas veces incluyen otros
campos (e.g. descripción o proyecto), e incluso el envı́o automático de su información al
almacenamiento central al detener el contador. Con el tiempo han incorporado pequeñas
mejoras, como la detección de los tiempos de inactividad, que las han hecho muy populares,
llegando incluso a ser una única interfaz minimalista en algunas aplicaciones [70].
3.1. Evolución de las aplicaciones privativas 29

3.1.5. Compatibilidad multi-plataforma


A pesar de que Windows ha seguido siendo el sistema operativo dominante en los entor-
nos ofimáticos, sus rivales, principalmente MacOS y Linux, han ganado suficiente terreno
estos últimos años como para ser un objetivo importante para todos los desarrolladores.
Además ese cambio en las cuotas de mercado ha propiciado un aumento en la heterogenei-
dad de los entornos laborales, con mezcla de diferentes sistemas operativos en terminales
con distintos propósitos. Por ello se ha hecho cada vez más común encontrar aplicaciones
multi-plataforma que a su habitual compatibilidad con Windows incluyen con otro sistema
operativo1 [59].
Aparte del diseño especı́fico para uno o más sistemas operativos, el éxito de lenguajes
interpretados como Java o Python ha permitido que existan aplicaciones totalmente inde-
pendientes de la plataforma, requiriendo únicamente la existencia de un intérprete para su
funcionamiento [59].

3.1.6. Interfaces web


La diversificación cada vez mayor de los sistemas operativos (ya comentada en el apar-
tado 3.1.5), muchas veces no sólo entre empresas sino entre los propios empleados y puestos
dentro de cada una, ha propiciado que se buscara una tecnologı́a lo más neutral e indepen-
diente de ellas posible. Con el auge de internet los navegadores web se convirtieron en un
elemento indispensable en todo entorno informático, y al basarse en lenguajes de marcado
e interpretados éstos resultaban independientes de los sistemas operativos y, en teorı́a, in-
diferentes al navegador. Por eso, una vez que las tecnologı́as web incorporaron elementos
y ((widgets)) amigables para el usuario, las interfaces web fueron ganando fuerza para este
tipo de aplicaciones.
Estas interfaces, normalmente basadas en HTML y lenguajes interpretados (e.g. Ja-
vaScript), pueden ser visualizadas en cualquier ordenador que disponga de una navegador
web (y en caso de emplear lenguajes interpretados, de los intérpretes correspondientes, ya
comunes en todos los sistemas operativos). Esta versatilidad y sencillez de cara al usuario
(el usuario medio sabe emplear sin problemas algún navegador web), unida a las ventajas
inherentes a los propios navegadores (marcado de páginas, historial, etc.), les han otorgado
gran popularidad estos últimos años [59].
Como toda aplicación web, su instalación se realiza en un servidor que atenderá las
peticiones HTTP que le lleguen. Habitualmente se requerirá autenticación para acceder
a cualquier página de la aplicación, redirigiendo a una página de login. Todas las demás
caracterı́sticas indicadas en apartados anteriores son igualmente aplicables a las interfaces
web.
A pesar de todas las ventajas citadas, lo cierto es que las diferencias que presentan los
navegadores a la hora de renderizar ciertos componentes de las páginas pueden producir
problemas imprevistos al visualizar interfaces con navegadores y versiones concretas (e.g.
elementos mal colocados o redimensionados, ofuscando otros cercanos) [71].
La popularidad de estas interfaces ha propiciado que algunos desarrolladores ofrezcan
directamente una instalación de su herramienta en un servidor propio, de manera que
el administrador a cambio de una cuota mensual sólo se preocupará de configurar en la
1
tras el SO de Microsoft el más habitual es MacOS, y luego GNU/Linux.
3.1. Evolución de las aplicaciones privativas 30

herramienta lo relativo a la lógica de negocio de su empresa y los permisos de los demás


usuarios, obviando las cuestiones más técnicas y todo lo relativo al propio servidor [72].

3.1.7. Capacidades de monitorización


Además de las funcionalidades de anotación del trabajo se fueron incorporando otras
que, si bien se podı́an emplear con el mismo fin, tienen una filosofı́a bastante diferente: las
capacidades de monitorización. Éstas, en vez de permitir la anotación del trabajo por parte
del usuario, monitorizan el uso que éste realiza del sistema, llevando un registro centralizado
de todos esos datos, habitualmente sólo visible para el administrador. Comunmente se
emplea la información de login para identificar al usuario, aunque también es posible asociar
directamente una máquina a un usuario concreto, de manera que el demonio monitorizador
o el almacenamiento central sepan a quién corresponden los datos.
La monitorización se puede realizar a diversos niveles, desde registrar todas las pulsacio-
nes de teclas hasta comprobar qué ventana posee el foco en cada momento, pasando por la
presentación de un campo de texto para justificar un perı́odo de inactividad en el ordenador.
Muchos usuarios avanzados emplean versiones locales para llevar un control personal de su
propio tiempo de trabajo, pero también se emplean en red para controlar a los empleados
en algunos entornos empresariales. Es muy habitual que incluyan capacidades para filtrar
protocolos HTTP, de correo o de mensajerı́a instantánea [73].
La finalidad de estas herramientas resulta más cercana a la supervisión de las horas de
trabajo, comprobando que el usuario no emplee el tiempo en actividades ociosas, que a la
supervisión del trabajo realizado en sı́. En cuanto a sus funcionalidades, tienen capacidades
para todas aquellas que no necesiten un enfoque activo del usuario [73] [74] [75].

3.1.8. Capacidades locales


Aunque el enfoque centralizado es el claro vencedor a dı́a de hoy, las capacidades total-
mente locales de estas aplicaciones han seguido evolucionando de una manera muy similar,
ya que siguen resultando para mucha gente la mejor opción para su ámbito personal. Por
ello, yendo más allá de resultar meros sustitutos electrónicos de las agendas, han incorpo-
rado la mayorı́a de las mejoras mencionadas (temporizador, aumento de la complejidad de
su lógica, extracción de gráficas, etc.) [76].
Además una parte de estas aplicaciones, siguiendo la filosofı́a de integración con el
entorno y transparencia para el usuario, han pretendido fusionarse con programas como
Microsoft Outlook o Lotus Notes, pasando a ser opciones o nuevas pestañas dentro de
éstas, resultando poco o nada intrusivas para usuarios poco experimentados [77] [78]. Por lo
general este enfoque implica un abanico de opciones más limitado, muchas veces intentando
asemejar la interfaz a otra ya conocida (e.g. anotaciones sencillas en un calendario).
Pese a toda esta evolución y mejoras, su uso no suele ir más allá del ámbito personal,
los profesionales ((freelance)) o empresas extremadamente pequeñas [79].

3.1.9. Versiones gratuitas


La era de la red de redes ha provocado que pese a que estas aplicaciones sean privativas
la mayorı́a de ellas incluya una versión gratuita, a modo de versión de prueba, con el fin
3.2. Evolución de las aplicaciones libres 31

de popularizarse, realizar marketing y captar nuevos clientes mediante la cata del producto.
Las limitaciones de la versión de prueba suelen variar según el tipo de programa que sea. Si
se trata de uno local, habitualmente la versión de prueba tiene un lı́mite de tiempo tras el
cual el usuario debe registrar su copia y pagar por una licencia a la empresa desarrolladora.
En las aplicaciones centralizadas es más común que limiten el número de entidades a
manejar (usuarios, proyectos, etc.), las capacidades de extracción de información o los
campos activos en los formularios, y de nuevo el usuario deberá pagar por una licencia
si requiere mayores capacidades. En las aplicaciones más completas suele haber diversas
’suites’con diferentes precios según el máximo de entidades a manejar y de funcionalidades
requeridas [80] [81] [82].

3.2. Evolución de las aplicaciones libres


Como ya se comentó en la introducción de este capı́tulo, las aplicaciones de software
libre para seguimiento de tareas empezaron a aparecer con la explosión de internet (apar-
tado 3 en la página 25), al igual que en casi todas las demás áreas. Ası́ pues, el software
libre llegó relativamente tarde a un nicho ya controlado por las aplicaciones privativas, el
cual a su vez se centra en SO propietarios [60].
Estas dos caracterı́sticas, el dominio previo por parte del software privativo y el target
mayoritatio de SO propietarios, han provocado que el impacto del software libre en este
sector sea realmente escaso, especialmente en el entorno empresarial. A pesar de ello, las
aplicaciones existentes han seguido una evolución general muy similar a la del software
privativo, aunque casi siempre con menor potencial.
Debido a que sus caracterı́sticas generales son las mismas, su historia más reducida
y a que el abanico de aplicaciones libres de seguimiento de tareas es tan escaso, en este
apartado comentaremos caracterı́sticas concretas de algunas aplicaciones especı́ficas como
ejemplos2 .

3.2.1. dotProject [83]


Se trata de una de las escasas aplicaciones libres de seguimiento de tareas para el entorno
empresarial. En ella los usuarios asignan de manera manual la duración de las diferentes
tareas, y éstas a los proyectos, el verdadero núcleo de la aplicación. Presenta diversas
caracterı́sticas, como generación de informes, administración de contactos o generación de
diagramas de Gantt, casi todo centrado al nivel del proyecto más que al de las tareas.
A pesar de tener un importante potencial a la hora de gestionar proyectos, una interfaz
anticuada e incluso incómoda (está totalmente basada en elementos estáticos) junto a un
modelo lógico que requiere en exceso su comprensión por parte del usuario final la hacen
poco recomendable hoy en dı́a para casi cualquier entorno laboral.
2
además de todas estas aplicaciones también disponemos de la versión anterior de PhpReport (apar-
tado 2.2 en la página 4) como un referente en este apartado
3.2. Evolución de las aplicaciones libres 32

3.2.2. Rachota [84]


Gestor personal de tareas con licencia libre Common Development and Distribution Li-
cense (CDDL) 1.0 desarrollado en Java, por tanto, programa libre multiplataforma. Con un
modelo sencillo, está pensado para que el usuario elabore un plan de tareas diario y luego
asigne las horas dedicadas a cada una de las tareas según trabaja sobre dicho plan. Permite
la clasificación de tareas por categorı́as y la obtención de estadı́sticas básicas, tanto de
tareas individuales como de las categorı́as.
Cuenta con una interfaz sencilla e intuitiva y con el potencial de resultar multiplataforma,
pero esto último tiene como efecto colateral que en la actualidad su integración con el
escritorio es claramente mejorable.

3.2.3. MyTime [85]


Herramienta de monitorización personal para entornos GNOME con licencia GPL versión
2. Fue ideada con el objetivo de que el usuario tuviera información fiable sobre el tiempo
empleado con cada aplicación mediante una serie de logs y estadı́sticas, a fin de poder
extraer conclusiones sobre el tiempo dedicado durante el trabajo.
Como se ha comentado, es de carácter únicamente personal, careciendo de soporte para
cruzar datos de múltiples usuarios o de caracterı́sticas habituales de otras aplicaciones de
monitorización (monitorización de grano más fino, inhabilitación de funcionalidades, etc.).
Pese a estos defectos, incluı́a una caracterı́stica innovadora: la centralización de información
mediante GNOME Online Desktop, pensado para mantener un almacenamiento centralizado
con los datos relativos al escritorio GNOME de un usuario, permitiendo acceder a ellos desde
cualquier terminal.
El fracaso de Online Desktop, una de sus funcionalidades con mayor potencial, hizo que
la aplicación no consiguiera el éxito esperado dentro de la comunidad de usuarios, por lo
que su desarrollo se encuentra paralizado a dı́a de hoy.

3.2.4. Project Hamster [86]


Gestor personal de tiempo desarrollado en Python para entornos GNOME, distribuido
con licencia GPL versión 3.
Probablemente el gestor de tareas libre de mayor éxito en la actualidad. Se trata de un
sencillo applet que se instala en la barra de herramientas, permitiendo posteriormente hacer
clic en él para introducir el nombre de la tarea que empezará a cronometrar a continuación.
Al igual que la mayorı́a de las aplicaciones de su mismo grupo, permite clasificar las tareas
según su categorı́a, para la posterior extracción de información estadı́stica.
Debido a que no presenta debilidades notables (más allá de las limitaciones propias de los
gestores personales de tiempo), en la actualidad sigue recibiendo un importante número de
actualizaciones destinadas tanto a mejorar casi todas sus funcionalidades como a solucionar
bugs, además de aumentar continuamente el número de traducciones disponibles.
Capı́tulo 4

Planificación de trabajo

En este capı́tulo comentaremos todo lo relativo a la funcionalidad de planificación de tra-


bajo incorporada a PhpReport. En primer lugar describiremos en qué consistió este apartado
y cuáles fueron sus objetivos concretos, para después detallar su diseño e implementación
y los resultados obtenidos posteriormente en sus pruebas.

4.1. Objetivos y descripción


4.1.1. Objetivos concretos
Los objetivos perseguidos con el trabajo relativo a este apartado son:

Estudiar las necesidades de planificación del entorno laboral.

Adición de capacidades de planificación de trabajo tanto a largo plazo como de ámbito


semanal.

Conexión de la planificación con el trabajo anotado.

4.1.2. Descripción general


PhpReport desde sus comienzos ha permitido la anotación de las horas de trabajo de
todos los empleados, con múltiples campos añadidos y mejoras a lo largo del tiempo que
le han permitido almacenar un mayor número de datos y relaciones según la lógica de
negocio lo fue requiriendo. Todo esto le ha permitido volverse una potente herramienta
para el control del trabajo de la empresa. Pero dicho control es totalmente retroactivo,
permitiendo únicamente llevar cuenta de lo que ya se ha realizado. Por este motivo se
fijó como objetivo dotar a PhpReport de una dimensión adicional, expandiendo su ámbito
de control a la planificación de tareas futuras.
La planificación del trabajo a realizar permitirá a PhpReport ampliar su control del
trabajo más allá del meramente realizado, permitiendo una sincronización más eficaz de
los diferentes trabajadores. También podrán visualizar la evolución del proyecto, tanto de
manera global como el trabajo individual de cada uno (no únicamente las horas trabajadas,
sino las estimadas restantes en cada apartado). De este modo los jefes de proyecto pueden
llevar un control mucho más eficaz de la evolución global del proyecto tanto a corto como
a largo plazo, o al nivel previamente existente de tarea individual anotada por el trabajador.

33
4.2. Análisis y diseño 34

No sólo se pretende añadir una dimensión nueva a la aplicación, sino conectarla con la
que ya existı́a previamente. Es decir, se permitirá vincular la anotación de actividades con la
planificación mediante una relación entre las tareas anotadas y las actividades planificadas.
Ası́ el usuario eligirá la actividad del proyecto ya planificada a la que pertenece la tarea
a anotar, y se almacenará como parte de ese proyecto. Este mecanismo permitirá que la
evolución del proyecto sea registrada conjuntamente y de manera natural junto con la
anotación del trabajo, requiriendo un esfuerzo adicional mı́nimo por parte del usuario.

4.2. Análisis y diseño


A la hora de realizar el diseño del modelo correspondiente a la planificación, se optó por
partir conceptualmente de la aplicación empleada previamente para tal fin en el entorno la-
boral. Dicha aplicación era tWiki [54] (ya comentada en el apartado 2.4.3 en la página 24),
un entorno wiki de código libre y fácilmente extensible, motivo por el cual dispone de gran
multitud de plugins que lo hacen extremadamente versátil, añadiéndole múltiples funciones
a su funcionamiento básico como wiki de texto.
Uno de esos plugins corresponde justamente a la metodologı́a de programación XP,
XPTrackerPlugin [55] (también mencionado en 2.4.3 en la página 24), proporcionando ca-
pacidades de planificación tal y como la metodologı́a propone:
Planificaciones a corto plazo, casi siempre de ámbito semanal.
La planificación, por la propia filosofı́a XP, es continuamente susceptible a cambios
sobre la marcha.
División del trabajo semanal de cada proyecto en tareas pequeñas sobre las cuales
anotar por separado.
Sin extendernos demasiado sobre dicho plugin, comentaremos que añade la planificación,
mayormente mediante tablas, del siguiente modo a tWiki:

El trabajo se divide en proyectos.


En cada proyecto pueden trabajar múltiples trabajadores.
Habitualmente, cada proyecto tiene una iteración por semana que aglutinará sus
tareas.
En las iteraciones se definen tareas llevadas a cabo por grupos de trabajadores.
Las tareas tienen un supervisor, normalmente el jefe del proyecto, que es el encargado
de validar que se ha realizado el trabajo adecuado.
Cada tarea contiene múltiples subtareas, cada una asignada a un trabajador concreto.
Para cada subtarea se asigna una duración en horas prevista, y además dispone de
campos para el número de horas trabajadas y horas pendientes (que no necesariamente
se tienen que corresponder con las inicialmente previstas, ya que según avanza el tra-
bajo se pueden producir desviaciones) que el usuario correspondiente rellenará según
avance.
4.2. Análisis y diseño 35

Cada tarea dispone de una página con campos de texto por defecto (razones del
retraso, aspectos importantes de la implementación, caracterı́sticas pendientes, etc)
en la que sus usuarios escribirán la información que estimen conveniente.

A fin de facilitar la transición a la nueva aplicación por parte de los usuarios, además
de por la eficacia que ha tenido en la empresa hasta el momento, se decidió mantener el
modelo empleado en tWiki en la mayor medida posible. Pero, además de la planificación
a corto plazo, en ciertos proyectos de la empresa se empleaba también un segundo tWiki
para llevar un control a largo plazo de modo más general y clásico, demostrando ser un
complemento importante en proyectos de entidad importante, especialmente en aquéllos a
fecha de fin.
Este segundo tWiki empleaba el mismo plugin que el de corto plazo, por lo cual se
decidió que el nivel correspondiente a las iteraciones se mapearı́a al apartado global del pro-
yecto (e.g. análisis, diseño, implementación) y las tareas y subtareas ahora serı́an secciones
más pequeñas de cada apartado. En el texto de la tarea se anotaban únicamente decisiones
tomadas y aspectos clave en lugar del desarrollo del trabajo diario realizado por el usuario.
Por este motivo se decidió añadir la planificación a los dos niveles: planificación semanal
(la habitual en XP) y planificación clásica a largo plazo.

4.2.1. Planificación a corto plazo


Como ya se comentó anteriormente, el modelo empleado en tWiki sirvió de base para la
planificación de PhpReport, por lo que se crearon los mismos niveles de entidades y campos
en estas últimas. Más concretamente, se crearon las siguientes entidades para realizar la
planificación semanal.

Iteration
Agrupa trabajo de un proyecto concreto en un perı́odo determinado. Almacena la si-
guiente información:

Fecha de inicio: el momento en el que empieza el trabajo del perı́odo.

Fecha de fin: el momento en el que termina el trabajo del perı́odo.

Nombre: nombre descriptivo para su identificación.

Resumen: texto como resumen del trabajo contenido.

Y se relaciona con otras entidades del siguiente modo:

Una o más iterations pertenecen a un proyecto.

Story
Recoge información sobre un apartado a llevar a cabo en una iteración especı́fica. Con-
tiene los siguientes datos:

Nombre: nombre descriptivo para su identificación.


4.2. Análisis y diseño 36

Aceptación: flag que rellenará el supervisor para indicar que la story ha cumplido los
requisitos previstos.

Posee las siguientes relaciones:

Una o más stories pertenecen a una iteration.

Pueden tener a un usuario como supervisor.

Pueden tener a otra story como sucesora temporal.

TaskStory
Describe un trabajo concreto dentro de una story. Se componen de los siguientes cam-
pos.

Nombre: nombre descriptivo para su identificación.

Riesgo: dificultad o peligro potencial que entraña el trabajo del perı́odo.

Fecha de inicio: el momento en el que empieza el trabajo del perı́odo.

Fecha de fin estimado: momento en el que se prevé que termine el trabajo del perı́odo.

Fecha de fin: el momento en el que termina el trabajo del perı́odo.

Horas estimadas: duración estimada del trabajo del perı́odo.

Horas de trabajo restantes: trabajo que se estima pendiente en el perı́odo.

Presenta estas relaciones:

Una o más taskStories pertenecen a una story.

Pueden tener a un usuario como trabajador asignado.

Pueden estar relacionadas con tareas introducidas por el usuario (de esta manera las
horas trabajadas se recogen automáticamente de la anotación del trabajo).

Pueden pertenecer a una taskSection (para vincular la planificación a corto y largo


plazo1 ; ver 4.2.2 en la página siguiente).

4.2.2. Planificación a largo plazo


La planificación a largo plazo empleaba un tWiki independiente, pero esencialmente con
la misma estructura que el semanal, por lo que aquı́ se ha optado por mantener un modelo
muy similar al que se le ha añadido conexión con las subtareas a corto plazo. Se compone
de las siguientes entidades.
1
un ejemplo sencillo serı́a una taskSection que recoge parte de la planificación global de implemen-
tación de una aplicación con la cual se relaciona una taskStory con la implementación de un fragmento
de código concreto por parte de una persona, o con cualquier otra tarea que surge durante el proceso
de codificación.
4.2. Análisis y diseño 37

Module
Contiene una etapa de trabajo global en un proyecto (e.g. diseño, implementación),
almacenando los siguientes datos:
Fecha de inicio: el momento en el que empieza el trabajo del perı́odo.
Fecha de fin: el momento en el que termina el trabajo del perı́odo.
Nombre: nombre descriptivo para su identificación.
Resumen: texto como resumen del trabajo contenido.
Y se relaciona con otras entidades del siguiente modo:
Uno o más modules pertenecen a un proyecto.

Section
Recoge información sobre un apartado a llevar a cabo en un module especı́fico. Contiene
los siguientes datos:
Nombre: nombre descriptivo para su identificación.
Resumen: texto como resumen del trabajo contenido.
Posee las siguientes relaciones:
Una o más sections pertenecen a un module.
Pueden tener a un usuario como supervisor.

TaskSection
Describe una tarea más concreta dentro de una section. Se componen de los siguientes
campos.
Nombre: nombre descriptivo para su identificación.
Riesgo: dificultad o peligro potencial que entraña el trabajo del perı́odo.
Horas estimadas: duración estimada del trabajo del perı́odo.
Presenta estas relaciones:
Una o más taskSections pertenecen a una section.
Pueden tener a un usuario como trabajador asignado.
Pueden estar relacionadas con una o más taskStories (para vincular la planificación
a corto y largo plazo2 ; ver 4.2.1 en la página anterior).
2
un ejemplo sencillo serı́a una taskSection que recoge parte de la planificación global de implemen-
tación de una aplicación con la cual se relaciona una taskStory con la implementación de un fragmento
de código concreto por parte de una persona, o con cualquier otra tarea que surge durante el proceso
de codificación.
4.2. Análisis y diseño 38

4.2.3. Estructura final de la BD


En la figura A.1 en la página 105 podemos ver la configuración final del modelo de la
base de datos una vez añadidas las capacidades de planificación3 .

Figura 4.1: diagrama E-R simplificado del modelo final de la BD

3
el diagrama ha sido simplificado para una mejor lectura, pero si se desea la versión completa, se
puede consultar en el anexo A.1 en la página 105
4.3. Implementación 39

4.3. Implementación
Tal y como ya se comentó y justificó en el apartado 2.3.2 en la página 7, la capa modelo
fue realizada completamente en PHP, con la excepción, claro está, de las nuevas tablas de
la base de datos. La capa se construyó en base al extendido modelo VO-DAO-Fachadas.
Aunque posteriormente se detallará cada apartado en PhpReport, podemos describir el
funcionamiento general del modelo del siguiente modo:

1. Los Value Object (VO) son objetos encargados de almacenar los datos provenientes
de base de datos. Habitualmente se construye uno por tabla (entidad), aunque en
ocasiones se pueden necesitar objetos para guardar datos adicionales a las entidades
o calculados. En dicho caso se les denomina Custom Object (CO). Suelen contener
únicamente métodos get y set para sus atributos, que mapean a los de la entidad
de base de datos. Cuando dichos atributos son claves foráneas se presentan diversos
enfoques: almacenar las claves, almacenar los VO correspondientes o no recuperarlo
con el propio objeto (se recuperarán más adelante si son necesarios).

2. Las operaciones individuales contra la base de datos son realizadas por los Data Ac-
cess Object (DAO). Lo más habitual es que cada DAO se encargue únicamente de
una tabla, con la excepción de las relaciones. En este último caso se suele preparar
para que a partir de un extremo de la relación se puedan obtener los elementos
asociados en el otro mediante un método, tanto en relaciones 1-1 como 1-N o N-N.
En todos los demás casos realizará operaciones sobre su propia tabla empleando el VO
correspondiente como almacén de datos (al trabajar con relaciones puede emplear los
VO correspondientes a las otras entidades o simplemente trabajar con su identificador
y delegar su posterior obtención).

3. Por último tenemos las fachadas, que se encargan de añadir una capa adicional para
reunir en un método todas las operaciones de DAO que requiere un caso de uso.
Pueden realizar varias llamadas sobre los DAO, llamadas condicionales, rellenar obje-
tos CO con atributos derivados u obtenidos de otras tablas, etc. Constituyen la parte
superior de la capa modelo que permite la comunicación con la capa web.

Siendo ésa la estructura habitual del modelo, PhpReport ha incluido en su nueva ver-
sión un nivel más de abstracción: las acciones. Dichos objetos, que veremos con más detalle
en su propio apartado (el 4.3.4 en la página 43), se encuentran entre las fachadas y los
DAO, encargándose ahora de la comunicación con estos últimos. Existe una acción por
cada método de las fachadas, y contienen el código que habitualmente tendrı́a dicho méto-
do, de manera que la fachada delega en él por completo. El objetivo de este enfoque es
proporcionar soporte para plugins individuales en cada función, de manera que la acción
buscará los plugins que le corresponden y los ejecutará cuando sea preciso (pueden existir
plugins pre-acción o post-acción). En la figura 4.2 en la página siguiente podemos observar
el comportamiento habitual de una acción junto con plugins.
Antes de entrar con más detalle en la implementación destacaremos que todo el código
en PHP correspondiente a esta etapa fue documentado con phpDocumentor (véase apar-
tado 2.3.3 en la página 20), el cual requerı́a introducir unos comentarios con una sintaxis
especı́fica antes de cada elemento que querı́amos documentar (archivo, objeto, función,
4.3. Implementación 40

Figura 4.2: diagrama UML de secuencia del funcionamiento normal de una acción y sus plugins
4.3. Implementación 41

atributo, etc.). No entraremos en detalle en la sintaxis, bastante sencilla [87], pero sı́ se
mantendrán los comentarios en todos los fragmentos de código incluidos, sirviendo como
ejemplos ilustrativos de su empleo.
Ahora se verán a fondo las diferentes etapas de la implementación.

4.3.1. Creación de la base de datos


Para la creación de la base de datos se empleó el programa tedia2sql (comentado en el
apartado 2.3.3 en la página 20), el cual permite obtener el conjunto de sentencias SQL Da-
ta Definition Language (DDL) de una BD a partir de un diagrama de clases que representa
la BD. Dicho diagrama se crea mapeando el diagrama Entidad-Relación (E-R) de un modo
sencillo [88], teniendo cada futura tabla una clase asociada. Ası́, pasándole el diagrama de
clases completo de la BD (anexo A.2 en la página 106) obtenemos todas las sentencias que
nos permiten crear dicha base de datos. El diagrama se realizó mediante un mapeo directo,
con el añadido de un campo serial a todas las entidades que actuará como su clave primaria,
ya que es el mejor modo de garantizar que nunca se producirán conflictos de ningún tipo
en las claves de los objetos.
Aunque tedia2sql es un programa extremadamente útil para crear una BD a partir de
su diagrama, presenta una limitación: no permite definir restricciones. Por ello se crearon
dos ficheros con sentencias DDL adicionales. El primero de ellos contiene las cláusulas
UNIQUE relativas a los campos que eran inicialmente las claves primarias en cada tabla
antes de añadir los identificadores internos. El otro recoge todas las demás restricciones que
permiten controlar aspectos como que ciertos números no sean negativos o que las fechas
de fin sean superiores a las de inicio.
Con estos tres ficheros se creó sin ningún problema o añadido la base de datos para
PhpReport en PostgreSQL.

4.3.2. Creación de los VO


Una vez que se tuvo la base de datos, se procedió a crear los objetos que nos permitirı́an
almacenar los datos de las entidades, los VO. Dichos objetos serı́an clases elaboradas en
PHP con atributos correspondientes a los campos de las entidades en la BD y métodos get
y set para cada uno de ellos. Se creó un VO por cada entidad nueva definida en la BD,
además de CO alternativos para la mayor parte de ellos que introducı́an o bien atributos
derivados o alguna clase relacionada devuelta directamente como objeto (y no simplemente
como su identificador). En estos casos se empleó la herencia para evitar duplicar aquel
código común tanto al VO como al CO.
En el diagrama4 4.3 en la página siguiente podemos observar todos los objetos creados,
tanto VO como CO.

No debemos olvidar que al VO de Task, ya existente en PhpReport, se le añadió un


atributo adicional correspondiente a la TaskStory asociada a él.
4
el diagrama A.7 en la página 111 muestra todos los VO existentes en PhpReport, incluyendo
aquéllos ya creados previamente.
4.3. Implementación 42

Figura 4.3: diagrama UML de los VO creados para la planificación

4.3.3. Creación de los DAO


El siguiente paso fue la creación de los DAO, los cuales permiten la realización de las
operaciones sobre la BD desde el modelo. Se implementó un objeto DAO por cada tabla
nueva de la BD (cada entidad y relación N-N nueva), empleando el lenguaje PHP para ello.
Todos descienden del DAO base que ya existı́a previamente en PhpReport (excepto los DAO
de las relaciones N-N, que descienden de uno base distinto). De dicho DAO base heredan
el atributo con la conexión a la BD, el método de inicialización, el cual crea la conexión
con la BD en base a los parámetros de configuración de PhpReport, un método abstracto
para rellenar el VO correspondiente con los datos de la tabla y un método para ejecutar
una sentencia SQL genérica y pasar los datos obtenidos al método anterior. El DAO base
para las relaciones N-N contiene también una conexión que se establece al crear el objeto,
pero todos los demás elementos los tiene duplicados ya que realmente trabaja con los dos
extremos de la relación, empleando la tabla de la relación para poder navegar de un lado
al otro. Por tanto, puede rellenar VO de ambos tipos y posee métodos diferenciados para
ello.
Las operaciones contra la BD son realizadas mediante la librerı́a de PostgreSQL de
PHP, que nos provee de métodos especı́ficos. La conexión se crea mediante el puerto, host,
nombre de la BD, usuario y password configurados en PhpReport (obtenidos mediante el
objeto gestor de configuración que ya existı́a previamente). Las operaciones contra la BD
son ejecutadas a partir de un string y la propia conexión, devolviendo en las de lectura un
array de arrays relacionales, que representa en el primer nivel las filas obtenidas y en el
relacional los resultados de los diferentes campos recuperados (el nombre del campo nos
devuelve su resultado). Cuando la operación no es de lectura, simplemente devolverá una
respuesta que será diferente de NULL en caso de que no haya habido errores.
Cada DAO5 posee las habituales operaciones Create Read Update Delete (CRUD) (con
la excepción de los DAO de las relaciones N-N, que no tienen la operación de actualizar ya
que no se dio ningún caso de uso en el que fuera realmente útil) y métodos para recuperar
5
en el anexo B.1 en la página 113 se muestra un fragmento de un DAO de PostgreSQL como ejemplo,
PostgreSQLModuleDAO.
4.3. Implementación 43

los objetos relacionados con él (delegando en el DAO del otro extremo), además de las
operaciones especı́ficas requeridas por cada uno.
Para cada DAO se creó una clase padre abstracta a fin de separar la implementación
para PostgreSQL de la capa superior, de manera que en caso de que fuera necesario se
pudieran crear DAOs para otros tipos de BD sin ningún problema. Para poder obtener la
implementación concreta de los DAO se dispone del objeto DAOFactory, el cual, siguiendo
el patrón ((factory)), nos devuelve la instancia correcta del tipo de DAO pedido (un método
por cada uno), tomando para ello el parámetro de configuración de PhpReport que nos
indica el tipo de BD empleada.
El diagrama6 4.4 en la página siguiente nos muestra todos los objetos creados relativos
al nivel DAO.
Al igual que en el apartado anterior, la relación entre Task y TaskStory implicó pequeños
cambios en el DAO correspondiente a Task. Concretamente se preparó para que recuperara y
rellenara el atributo nuevo de TaskVO, y también se añadieron los métodos correspondientes
a la relación, para recuperar el objeto relacionado.
Por último destacaremos el uso de los errores especı́ficos ya definidos previamente en
PhpReport para los siguientes casos:

Fallo en la conexión a BD. Error en la ejecución de la query.

Violación de UNIQUE. Tipo de dato inválido.

4.3.4. Creación de las acciones


Las acciones, encargadas de implementar los diferentes casos de uso en base a los
métodos proporcionados por los DAOs, fueron la siguiente etapa a implementar. Dichos
elementos heredan de una acción base que contiene un método abstracto en el cual cada
acción tendrá el código correspondiente al caso de uso que implementa, que incluirá todas
las llamadas a los DAOs necesarias, además de código propio para manejar los datos re-
cuperados. Todas las acciones a la hora de ejecutarse buscarán en primer lugar si poseen
plugins pre-acción, y en caso afirmativo los ejecutarán. A continuación ejecutarán el método
que contiene su código propio del caso de uso. Finalmente, comprobarán la existencia de
plugins post-acción, y los ejecutarán si están definidos. En ambos tipos de plugins es el
objeto gestor de configuración el encargado de recuperar los nombres de aquéllos asignados
a la acción a través del fichero de configuración.
En todas las acciones los parámetros de entrada se introducen en el momento de crear
la acción, la cual los almacena en atributos propios para poder disponer de ellos en el
momento de la ejecución del código. También destacaremos que en aquellos casos en que
no se espere el retorno de un resultado real sino simplemente de una confirmación dicho
valor se corresponderá con un 0 (y un -1 será el valor de error).
En el diagrama 4.5 en la página 45 tenemos una breve explicación sobre las acciones
que se crearon en base a los nuevos métodos de las fachadas.
6
se puede consultar el conjunto de todos los DAOs existentes en PhpReport en los diagra-
mas A.3 en la página 107, A.4 en la página 108, A.5 en la página 109 y A.6 en la página 110.
4.3. Implementación 44

Figura 4.4: diagrama UML de los DAO creados para la planificación


4.3. Implementación 45

Figura 4.5: diagrama UML de los métodos nuevos en las fachadas para la planificación
4.4. Pruebas y resultados obtenidos 46

4.3.5. Creación de las fachadas


Una vez que se tuvieron las acciones, las fachadas se convirtieron en el siguiente paso
a implementar. Simplemente se tratan de objetos que siguen el patrón ((facade)), es decir,
disponen de métodos que sirven para ocultar su implementación en base a capas de códi-
go inferiores [89]. Todas las fachadas de PhpReport son objetos abstractos con métodos
estáticos, ya que no disponen de ningún tipo de atributo, simplemente ofrecen funciones
que componen la interfaz de la capa modelo.
En concreto se creó una fachada nueva, Coordination, con todos los métodos de los
casos de uso relativos a la planificación, y además se amplió la fachada User con nuevos
métodos necesarios en la interfaz para disponer de los usuarios adecuados en los procesos
de asignación y desasignación en la planificación.
En el diagrama 4.5 en la página anterior podemos ver los cambios realizados a este
nivel7 (además de una breve explicación sobre las acciones correspondientes que se crearon).
En la figura 4.6 en la página siguiente incluimos un diagrama de secuencia con todo los
pasos por los que atraviesa la creación de una Task Story, para poder ver en funcionamiento
toda la capa descrita hasta ahora.

4.4. Pruebas y resultados obtenidos


Una vez que se tuvo la implementación de cada uno de los niveles, se realizaron pruebas
de diversos tipos y niveles de formalidad. De todas las pruebas realizadas en este apartado
no se obtuvieron resultados especiales más allá de confirmar el correcto funcionamiento de
todo el código y, en el caso de los tests de unidad, de asegurar que seguı́a siendo ası́ en
todo momento. Los errores que se pretendı́a hallar con ellos eran más relativos a fallos
en la implementación que en el diseño, debido a que la lógica de negocio subyacente era
bastante sencilla. Todas las pruebas, fuesen formales o no, se realizaron sobre una base de
datos limpia creada con este único objetivo.
Recordamos que PhpReport dispone de una serie de suites que aglutinan los tests de
unidad facilitando su ejecución. En cada conjunto de tests de unidad se comentará en
qué suite se añadieron, pero siempre se podrán ejecutar todos los existentes mediante la
llamada PHPReportGeneralSuite.
Las pruebas realizadas sobre esta parte las detallaremos en base al nivel en el que se
aplicaron.

4.4.1. Pruebas de VOs


A pesar de la extremada simplicidad de los VOs, se optó por crear tests unitarios sobre
ellos, siguiendo la filosofı́a que presentaba PhpReport. Para ello se creó un test unitario
por cada VO que luego se probarı́a mediante PhpUnit (herramienta ya vista en el aparta-
do 2.3.2 en la página 9). Cada test unitario posee un método de inicialización en el que se
crea el VO, uno final en el que se destruye y un método por cada atributo que prueba su
set y su get (asigna y comprueba el valor dos veces).
7
además el diagrama A.8 en la página 112 nos muestra la composición final de todas las fachadas
en PhpReport.
4.4. Pruebas y resultados obtenidos 47

Figura 4.6: diagrama UML de secuencia del proceso completo de creación de una Task Story
4.4. Pruebas y resultados obtenidos 48

Se añadieron los nuevos tests a la suite ya existente en PhpReport que aglutina todos
los relativos a los VOs.

4.4.2. Pruebas de DAOs


En primera instancia cada DAO implementado fue testeado con un sencillo código de
prueba incluido en su propio archivo, al cual se le añadı́an pruebas sencillas de los métodos
según estos se implementaban. La finalidad de estas pruebas era simplemente obtener
mediante la ejecución del archivo una comprobación rápida, bien por impresión por lı́nea
de comando o con comprobación directa en la BD, de que cada método nuevo funcionaba
correctamente, sin intención alguna de resultar formales o prevenir posibles regresiones de
código.
Una vez que se completaron los DAOs y no se detectaron problemas en ellos se pro-
cedió a elaborar un conjunto de pruebas formales que facilitaran el aseguramiento de un
código funcional evitando posibles regresiones. Para ello se empleó de nuevo la herramienta
PHPUnit. Los ficheros de test corresponderı́an cada uno a una implementación de un DAO,
poseyendo al menos un test por cada función encargado de comprobar su funcionamiento
correcto, además de algunos para comprobar situaciones de error tı́picas (e.g. buscar por
un identificador nulo o inexistente). Además incluyen métodos para inicializar y finalizar la
configuración del test (habitualmente la creación del propio DAO y de uno o más VOs que
se emplearán en las pruebas).
Los tests unitarios se incluyeron en la suite de tests unitarios para DAOs básicos ya
presente en PhpReport.

4.4.3. Pruebas de acciones


El siguiente nivel de pruebas fue el correspondiente a las acciones. En este nivel se
optó por emplear sencillas pruebas de código al final de cada acción de un estilo similar a
las primeras comentadas para los DAOs. Debido a que en casi todos los casos cada acción
implicaba la llamada directa a una o dos operaciones de DAOs con un paso sencillo de
parámetros, y que en los pocos casos en que no era ası́ la lógica añadida era sumamen-
te sencilla, no se vio ventaja alguna en la creación de pruebas de unidad para prevenir
regresiones en este punto.
Las fachadas no tuvieron pruebas serias de ningún tipo ya que suponı́an simplemente la
llamada directa de una acción sin lógica añadida alguna.
Capı́tulo 5

Extracción de datos avanzada

A continuación se abordará el trabajo relacionado con las capacidades de extracción


de datos avanzada añadidas a PhpReport. De nuevo se empezará describiendo de manera
general y citando los objetivos concretos, para a continuación describir a fondo el diseño y
la implementación, y finalmente los resultados de las pruebas que se le aplicaron.

5.1. Objetivos y descripción


5.1.1. Objetivos concretos
En este apartado se persiguieron los objetivos siguientes:

Analizar las necesidades, tanto actuales como posibles en el futuro, de extracción de


informes de datos en el entorno laboral.

Creación de los métodos de extracción de datos (lo más genéricos y potentes posibles).

Verificación exhaustiva del resultado de la extracción de datos más complejos y sensi-


bles a errores (principalmente, horas extra trabajadas y horas de vacaciones pendien-
tes).

5.1.2. Descripción general


En sus primeras versiones PhpReport se concibió como una aplicación de anotación de
horas de trabajo relativamente sencilla, con un número de campos de datos a almacenar
reducido. Con el tiempo el número de campos a almacenar ha ido aumentando, bien por
aumento de la complejidad de la lógica de negocio o por el simple hecho de querer guardar
nueva información, pudiendo ser tanto campos adicionales como entidades o relaciones
nuevas. Esto ha provocado que la extracción efectiva de información de la aplicación se
volviera más compleja, requiriendo la lectura de múltiples páginas o incluso cálculos externos
en muchos casos.
Dicho problema será solventado dotando a PhpReport de capacidades de extracción
de datos avanzada destinadas principalmente a la generación de informes que faciliten la
lectura de datos cruzados y/o derivados. De este modo todos los trabajadores, y muy
especialmente los administradores y jefes de proyecto, podrán acceder a información de
alto nivel, siempre más representativa para el usuario, a partir de los datos más básicos que

49
5.2. Análisis y diseño 50

almacena PhpReport, como por ejemplo saber las horas de vacaciones pendientes de los
empleados, calculadas a partir de la duración de su jornada y las horas trabajadas ese año.
Todo el proceso de extracción y cruce de datos se basará en las relaciones existentes
entre las entidades de la base de datos. Dichas capacidades de extracción de información
serán lo más genéricas posibles, con el objetivo de que realizar nuevos cruces de datos
requiera simplemente llamar a los mismos métodos con otros parámetros o realizar un
número diferente de llamadas, pero siempre evitando en la medida de lo posible la creación
de nuevas funciones a nivel de DAO.

5.2. Análisis y diseño


El análisis y diseño de esta parte se enfocó más a la determinación de los requisitos
de datos exactos de los diferentes informes, tanto reales como potenciales, empleados por
los usuarios en la empresa. Esta labor de análisis comenzó por un estudio de los informes
obtenidos mediante la versión anterior de PhpReport y otras herramientas empleadas en el
entorno empresarial. Una vez que se tuvo una perspectiva sobre los requisitos habituales
en este tipo de información se procedió a preguntar a un pequeño grupo de usuarios,
principalmente jefes de proyecto, qué clase de informes les eran más útiles, cuáles echaban
en falta y qué modificaciones harı́an sobre los existentes.
Tras obtener una información en su mayorı́a consensuada en la empresa sobre la impor-
tancia de los diferentes informes se procedió a abstraer dicha información para obtener el
modelo de informe más genérico posible que luego se pudiera personalizar en base a dife-
rentes parámetros. En ese proceso se llegó a las siguientes conclusiones sobre los informes:

Ya que los informes requeridos son siempre sobre las tareas, todos giran en torno a
la entidad Task, por lo que será su DAO el que realice el grueso del trabajo.

En los informes se presentan conjuntos de datos obtenidos mediante el sesgo en base


a diferentes factores de las horas almacenadas en Task. Por tanto, se deben emplear
cláusulas GROUP BY de Structured Query Language (SQL) para agruparlos.

De manera genérica existen dos tipos de informes: aquéllos que recuperan datos
relacionados con un elemento (e.g. las horas trabajadas por cada uno de los usuarios
en un proyecto concreto, es decir, los datos de un proyecto agrupados en base a los
usuarios) y los que trabajan con todos los datos almacenados (e.g. horas trabajadas
por cada uno de los usuarios para cada cliente, es decir, todos los datos agrupados
en base a combinaciones de usuario y cliente).

También se creó una función en el DAO de Task que nos permite obtener las horas
de vacaciones empleadas por los usuarios entre dos fechas, un dato que nos permi-
tirá obtener posteriormente el número de horas de vacaciones que les restan.

Existen dos datos especialmente importantes para los usuarios y con una lógica más
compleja que implica varias entidades:

• Horas extra trabajadas (tanto hasta el momento actual como a una fecha con-
creta).
5.3. Implementación 51

• Vacaciones pendientes en el año actual.

Para comprender dicha lógica se estudió la implementación de su cálculo realizada en


la versión anterior de PhpReport, además de discutirlo con algunos miembros de la
empresa, ya que en casos muy puntuales (como en el manejo de los años bisiestos)
no habı́a un consenso claro sobre la polı́tica a adoptar.

Una vez obtenidas estas conclusiones se decidió que se dotarı́a al DAO de Task de
capacidades de extracción de datos, tanto relacionados con un elemento concreto (pro-
yecto, cliente, usuarios, etc.) como de manera general, agrupándolos en diversos niveles y
permitiendo el filtrado por fechas de inicio y/o fin.
En cuanto al cálculo de horas extra, se optó por integrar su lógica a nivel de una acción
independiente, por ser especialmente compleja, propensa a modificaciones en el futuro e
implicar un importante número de entidades (User, Task, Journey History, City History,
City...). En el caso del cálculo de vacaciones pendientes, se creó un método en el DAO de
Task que nos permitiera recuperar las horas de las tareas asociadas al proyecto simbólico
para las vacaciones1 , delegando el resto de la lógica en otra acción independiente. En ambos
casos se permitirı́a tanto la obtención de los datos para un único usuario como un informe
general para todos, además del filtrado por fechas de inicio y/o fin. La extracción de los
datos bien para un único usuario o para todos como informe general fue otra caracterı́stica
que se optó por añadir. Las acciones obtendrı́an los datos base mediante operaciones de los
diferentes DAOs, incluyendo en el caso del de Task la operación de extracción avanzada de
datos añadida en el paso anterior.
Ya antes de comenzar a implementar se decidió que la etapa de pruebas de este apartado
serı́a especialmente importante debido a los problemas habituales que se habı́an presentado
en el cálculo de las horas extra y de las vacaciones pendientes en ocasiones anteriores. Para
ello se contrastarı́an los datos con los obtenidos mediante el código de la versión anterior
de PhpReport.

5.3. Implementación
Como se comentó la sección anterior, la base del código destinado a las labores generales
de data-mining se encontrarı́a en el DAO de Task, mientras que aquellos informes que
requiriesen lógica más compleja tendrı́an dicho código añadido en una acción especı́fica.
Además se creó un método para obtener las horas de vacaciones utilizadas por cada usuario.
Debido a la especial importancia de estos métodos, hablaremos de su implementación con
más detalle a continuación.

5.3.1. Funciones básicas de extracción de datos


Con el fin de poder extraer la información necesaria asociada con las tareas almacenadas
en BD se crearon dos métodos genéricos: uno para la obtención de datos asociados a un
elemento concreto y el otro para la generación de informes generales de todos los usuarios
1
para no complicar el modelo con más entidades se optó por emplear un proyecto especial para
asociar a él las horas de vacaciones que cada empleado ha gastado, pudiendo configurar el nombre del
proyecto empleado para tal fin dentro del fichero de configuración.
5.3. Implementación 52

sin filtrados especı́ficos. También se creó un método más sencillo para obtener las horas de
vacaciones utilizadas por cada usuario.

Informes sobre un elemento especı́fico


Cuando se requiere información relativa a un elemento concreto es necesario filtrar
primero las tareas almacenadas en base al atributo correspondiente antes de agrupar los
datos, y para eso se creó la función GetTaskReport en el DAO de Task. Dicha función
toma los siguientes parámetros:

El objeto acerca del cual queremos extraer el informe (actualmente se permiten


UserVO, CustomerVO y ProjectVO).

La fecha de inicio del intervalo requerido (en caso de no pasarse o ser nula, no se
establece lı́mite inferior alguno para la fecha de la tarea).

La fecha de fin del intervalo requerido (en caso de no pasarse o ser nula, se toman
los datos hasta la fecha actual).

Atributo opcional para el primer nivel de agrupamiento (actualmente acepta los strings
USER, PROJECT, CUSTOMER, TTYPE y STORY, definidos en un enumerado en la clase
abstracta padre del DAO).

Atributo opcional para el segundo nivel de agrupamiento (actualmente acepta los


strings USER, PROJECT, CUSTOMER, TTYPE y STORY, definidos en un enumerado en la
clase abstracta padre del DAO).

Mediante estos cinco atributos, cuyos valores válidos son fácilmente expandibles, se pue-
den extraer múltiples conjuntos de datos para la generación, tanto directa como indirecta,
de casi cualquier informe potencial sobre un elemento concreto requerido en la empresa.
El siguiente ejemplo ayudará a entender mejor el funcionamiento y utilidad del método:
se quiere saber cuántas horas ha trabajado cada empleado en cada uno de los proyectos del
cliente ((Wealthy Client)) durante el año 2009. Para ello se invocará el método pasándole
como parámetros el objeto CustomerVO de ((Wealthy Client)), las fechas de inicio y fin de
2009, y los strings PROJECT y USER. Con estos parámetros el método ejecutará internamen-
te la siguiente sentencia SQL:

SELECT projectid, usrid, SUM(end-init) / 60.0 AS add hours FROM task


WHERE customerid = wealthy client id AND date >= ’2009-01-01’ AND
date <= ’2009-12-31’ GROUP BY projectid, usrid ORDER BY projectid, usrid

la cual nos devolverá las horas trabajadas por cada usuario en cada proyecto (campos
add hours, userid y projectid respectivamente).

Informes generales
En el caso de querer informes generales sin filtrar por ningún elemento se usa la función
GetGlobalTaskReport del DAO de Task, la cual acepta los siguientes parámetros:
5.3. Implementación 53

La fecha de inicio del intervalo requerido (en caso de no pasarse o ser nula, no se
establece lı́mite inferior alguno para la fecha de la tarea).

La fecha de fin del intervalo requerido (en caso de no pasarse o ser nula, se toman
los datos hasta la fecha actual).

Atributo para el primer nivel de agrupamiento (actualmente acepta los strings USER,
PROJECT, CUSTOMER, TTYPE y STORY, definidos en un enumerado en la clase abstracta
padre del DAO).

Atributo opcional para el segundo nivel de agrupamiento (actualmente acepta los


strings USER, PROJECT, CUSTOMER, TTYPE y STORY, definidos en un enumerado en la
clase abstracta padre del DAO).

Atributo opcional para el segundo nivel de agrupamiento (actualmente acepta los


strings USER, PROJECT, CUSTOMER, TTYPE y STORY, definidos en un enumerado en la
clase abstracta padre del DAO).

Las diferentes combinaciones posibles de los cinco atributos, de nuevo fácilmente ex-
pandibles, nos permiten extraer un gran número de informes generales de gran utilidad para
la empresa, tanto directa como indirectamente.
Ahora presentaremos otro ejemplo para ilustrar el uso del método: se quiere saber
cuántas horas ha trabajado cada usuario para cada proyecto en cada tipo de tarea durante
el año 2009. Para ello se invocará el método pasándole como parámetros las fechas de
inicio y fin de 2009, y los strings USER, PROJECT y TTYPE. Con estos parámetros el método
ejecutará internamente la siguiente sentencia SQL:

SELECT usrid, projectid, ttype, SUM(end-init) / 60.0 AS add hours FROM


task WHERE date >= ’2009-01-01’ AND date <= ’2009-12-31’ GROUP BY usrid,
projectid, ttype ORDER BY usrid, projectid, ttype

la cual nos devolverá las horas trabajadas por cada usuario en cada proyecto por cada tipo
de tarea (campos add hours, usrid, projectid y ttype respectivamente).
En la figura 5.1 en la página siguiente incluimos un diagrama de secuencia con todo los
pasos por los que atraviesa la obtención de un informe de trabajo User-Story, para poder
ver en funcionamiento toda la capa descrita hasta ahora, y la figura 5.2 en la página 55
nos muestra un ejemplo del posible resultado obtenido con dicho informe.

Horas de vacaciones utilizadas


El método getVacations, de nuevo en el DAO de Task, nos devuelve las horas disfruta-
das como vacaciones por los usuarios en un intervalo, recibiendo los siguientes parámetros:

El usuario del cual queremos saber las vacaciones utilizadas (objeto UserVO).

La fecha de inicio del intervalo requerido (en caso de no pasarse o ser nula, no se
establece lı́mite inferior alguno para la fecha de la tarea).
5.3. Implementación 54

Figura 5.1: diagrama UML de secuencia del proceso completo de obtención de un informe
User-Story
5.3. Implementación 55

Figura 5.2: ejemplo de informe User-Story


5.3. Implementación 56

La fecha de fin del intervalo requerido (en caso de no pasarse o ser nula, se toman
los datos hasta la fecha actual).

El método nos devolverá el número de horas de vacaciones utilizadas (las asociadas al


proyecto de vacaciones) dentro del campo add hours del array devuelto.

5.3.2. Acciones especı́ficas


La extracción de ciertos informes concretos implicaba una lógica de negocio lo suficiente-
mente compleja como para que su inclusión a nivel de DAO fuera claramente desaconsejable.
Por ello se optó por crear acciones especı́ficas que emplearan llamadas básicas a los DAOs
para obtener los datos, incorporando ellas el código más complejo que los maneja. Ambas
acciones, por estar claramente enfocadas a la entidad User, serı́an empleadas por la fachada
de usuarios.

Cálculo de horas extra


La acción ExtraHoursReportAction es la que nos proporciona las horas extra tra-
bajadas por los usuarios, además de otros datos calculados relacionados con ellas. En el
momento de crearla se le pasan los siguientes parámetros:

La fecha de inicio del intervalo requerido.


La fecha de fin del intervalo requerido.
El usuario del cual queremos saber las horas extra (objeto UserVO), o un valor nulo
si nos interesa el informe con las horas extra de todos los usuarios almacenados (se
devolverán tanto las de cada uno como el total sumado entre todos).

Antes de mostrar el seudocódigo de este cálculo2 haremos una breve descripción del
modo de obtener las horas extra en base a otras categorı́as de horas calculadas:

Horas extra: se obtienen de restar a las horas trabajadas las horas trabajables del
mismo intervalo.
Horas trabajadas: como su propio nombre indica, las horas anotadas por un trabajador
en tareas que no fuesen del proyecto vacaciones.
Horas trabajables: son las horas que le corresponden a un trabajador en un intervalo.
Se calculan a partir de su histórico de jornada, teniendo en cuenta los diferentes
festivos existentes (que a su vez dependen del histórico de ciudad).

El cálculo de las horas trabajables representa la parte más compleja de toda la acción, ya
que implica el cruce de diversos históricos (de ciudad y de jornada) y su posterior aplicación
al calendario laboral de las diferentes ciudades. En cambio la obtención de las horas traba-
jadas fue prácticamente directa de la BD mediante el DAO de Task. Podemos comprobarlo
en el seudocódigo incluido en la sección de código 5.1 en la página siguiente.

2
el apartado B.2 en la página 116 contiene el código correspondiente a la lógica de negocio de la
acción por si se quiere consultar.
5.3. Implementación 57

1 Como e n t r a d a t e n e m o s USER ( u s u a r i o d e l que n o s i n t e r e s a o b t e n e r l a i n f o r m a c i o n ; p a r a m e t r o o p c i o n a l ) ,


INIT ( f e c h a de i n i c i o d e l i n t e r v a l o ) y END ( f e c h a de f i n d e l i n t e r v a l o )
2
3 i f ( i s n u l l (USER) )
4 {
5 Obtenemos t o d o s l o s u s u a r i o s −> USUARIOS
6 }
7 else
8 {
9 I n t r o d u c i m o s USUARIO en USUARIOS
10 }
11
12 f o r e a c h ( USUARIOS a s USUARIO )
13 {
14 Obtenemos e l i n f o r m e de h o r a s t r a b a j a d a s e n t r e INIT y END p a r a USUARIO
15
16 Recuperamos t o d a s l a s e n t r a d a s d e l h i s t o r i c o de j o r n a d a s e n t r e INIT y END p a r a USUARIO
17
18 Recuperamos t o d a s l a s e n t r a d a s d e l h i s t o r i c o de c i u d a d e s e n t r e INIT y END p a r a USUARIO
19
20 Cruzamos ambos c o n j u n t o s de e n t r a d a s p a r a o b t e n e r t o d o s l o s p e r i o d o s en b a s e a ambos campos −>
HISTORIES
21
22 f o r e a c h ( HISTORIES a s HISTORY )
23 {
24 C a l c u l a m o s e l numero de d i a s de t r a b a j o en e l p e r i o d o ( metodo e s p e c i f i c o p a r a e l l o )
25
26 Recuperamos e l numero de f e s t i v o s e x i s t e n t e s en e s e p e r i o d o en l a c i u d a d c o r r e s p o n d i e n t e
27
28 Obtenemos e l numero de h o r a s ” t r a b a j a b l e s ” r e s t a n d o a l numero de d i a s de t r a b a j o e l de
f e s t i v o s y m u l t i p l i c a n d o por l a jornada
29 }
30
31 Computamos l a s h o r a s e x t r a d e l u s u a r i o r e s t a n d o a l numero de h o r a s t r a b a j a d a s r e c u p e r a d a s en e l
i n f o r m e e l numero de h o r a s ” t r a b a j a b l e s ” c a l c u l a d o
32 }
33
34 Devolvemos t o do s l o s r e s u l t a d o s o b t e n i d o s

Código 5.1: seudocódigo del cálculo de horas extra, código de ExtraHoursReportAction.php

Los datos se devuelven de nuevo en un array relacional que incluye para cada usuario,
referenciado por su login, los tres tipos de horas mencionadas anteriormente, relativas al
intervalo pasado a la acción, y además el número total de horas extra acumuladas por el
usuario hasta el dı́a actual. También se incluirá un conjunto adicional con los datos totales
de todos los usuarios en caso de tratarse del informe general.
En la figura 5.3 en la página siguiente podemos observar un posible resultado del infor-
me de horas extra y vacaciones pendientes a modo de ejemplo.

Cálculo de vacaciones pendientes


Para conocer el número de horas de vacaciones que un usuario tiene disponibles para
un intervalo concreto3 se emplea la acción GetPendingHolidayHoursAction. Durante la
creación le pasaremos los siguientes parámetros:

La fecha de inicio del intervalo requerido.

La fecha de fin del intervalo requerido.

El usuario del cual queremos saber las vacaciones pendientes (objeto UserVO), o
un valor nulo si nos interesa el informe con las vacaciones pendientes de todos los
3
aunque se permite el cálculo con intervalos concretos, y en ciertas ocasiones puede ser útil, para
conocer el número real de horas de vacaciones pendientes se debe seleccionar el comienzo del año actual
como inicio del intervalo, ya que es el momento en que habitualmente se reiniciará el número de festivos
disponibles.
5.3. Implementación 58

Figura 5.3: ejemplo del informe de horas extra y vacaciones pendientes de los usuarios
5.4. Pruebas y resultados obtenidos 59

usuarios almacenados.

La obtención de las horas de vacaciones disponibles es bastante sencilla4 , consistien-


do primero en el cálculo del número de horas que le corresponden a un trabajador en
el intervalo indicado en base a su jornada (en el fichero de configuración se almacena el
número correspondiente a un año con jornada estándar de ocho horas) para a continuación
restarle las que ya han sido gastadas (obtenidas con el método detallado anteriormente
en 5.3.1 en la página 53).
Los datos se devuelven de nuevo en un array relacional que incluye para cada usuario,
referenciado por su login, el número de horas de vacaciones que tiene disponibles.

5.4. Pruebas y resultados obtenidos


Al principio de este capı́tulo comentamos la especial importancia que se le dio a las
pruebas debido a la complejidad del código, especialmente en el cálculo de las horas extra,
lo que las hacı́a especialmente propensas a errores de codificación, casos no considerados y
regresiones por posteriores modificaciones menores.

Pruebas de DAOs
Los nuevos métodos del DAO de Task cuentan con sus propios tests de unidad dentro
de la clase PostgreSQLTaskDAOBasicTests. El método getTaskReport cuenta con un
conjunto de pruebas de unidad que testean varias combinaciones diferentes de parámetros
(la clase de objeto sobre la que se generan pruebas y la inclusión o no de fechas y agru-
pamiento), mientras que getVacations y getGlobalTaskReport tienen cada uno una
prueba que las testea. En todas las pruebas se procedió a crear en BD los mı́nimos obje-
tos necesarios para la extracción del informe, y posteriormente se realizó dentro del propio
test de unidad el cálculo de las horas acumuladas, números que después son comparados
con los devueltos por el método del DAO. Los resultados obtenidos fueron simplemente la
confirmación de que los métodos funcionaban siempre del modo previsto.

Pruebas de acciones
El cálculo de las horas extra fue en la versión anterior de PhpReport fuente de varios
errores de programación, en ocasiones exclusivos de la codificación y en otros de casos
especiales no detectados en la propia lógica de negocio. Por ello se optó por crear tests
unitarios para la comprobación de la acción correspondiente. Para lograrlo se necesitaba
un código adicional que calculara las horas extra a fin de comparar ambos resultados, y se
optó por coger el empleado en la versión anterior de PhpReport y guardarlo por separado
en un archivo nuevo.
Dicho código necesitaba una base de datos con la estructura antigua, ası́ que se creó otra
base de datos de pruebas con dicho esquema, rellenándola con un dump de la BD real. A
fin de contener los mismos datos, la base de datos de prueba de la versión actual tendrı́a
el mismo contenido migrado al esquema nuevo.
4
en el anexo B.3 en la página 119 se puede ver el código correspondiente a la lógica de negocio de
la acción.
5.4. Pruebas y resultados obtenidos 60

Los tests se realizaron con consultas de distintos intervalos de tiempo desde el 1 de


enero del 2005 hasta la fecha actual. Concretamente se tienen los siguientes conjuntos de
pruebas:

ExtraHoursReportActionLargeTest: compara informes a intervalos de un año y


seis meses.

ExtraHoursReportActionMediumTest: compara informes a intervalos de tres meses


y un mes.

ExtraHoursReportActionSmallTest: compara informes a intervalos de 15 dı́as.

ExtraHoursReportActionVerySmallTest: compara informes a intervalos siete dı́as.

Todas las clases de test descienden de la misma, ExtraHoursReportActionTest, la


cual contiene un método genérico que compara informes a partir de un intervalo pasado
como parámetro (se pasa en un string con la sintaxis empleada por la clase DateTime de
PHP [90]), por lo que únicamente heredan dicho método y lo ejecutan pasándole distintos
intervalos. Cada intervalo diferente es un test de unidad que se detendrá en cuanto detecte
una diferencia en los datos comparados.
En un principio se comparaban para cada usuario los cuatro datos devueltos (horas extra
en el intervalo, horas extra totales, horas trabajables y horas trabajadas), pero durante el
proceso de testeo se detectaron errores que, una vez contrastados con cálculos hechos a
mano, fueron situados en el código antiguo de PhpReport. Por ello, en lugar de corregir dicho
código, se optó por comparar únicamente los datos que se sabı́a que estaban bien calculados,
que eran los correspondientes a aquellos intervalos que no contenı́an una compensación de
horas extra5 para el usuario. Con dicho objetivo se creó un método en el código antiguo que
devuelve los usuarios válidos en un intervalo dado, para comparar únicamente sus resultados.
También se tuvo que dejar de comparar los datos sumados para todos los usuarios ya que
el código antiguo consideraba a todos los usuarios para dicho cálculo, cuando únicamente se
deben considerar los que pertenecen al grupo staff (los trabajadores actuales de la empresa).
Aclaramos que el problema no se debió a un reinterpretación de la lógica del informe, sino
a un error en la programación al no considerar dicho caso (el informe devuelto contenı́a
datos incoherentes, aunque difı́ciles de detectar, debido a dicho error).
Una vez realizadas ambas limitaciones sobre los datos a comparar ya se pudieron ejecutar
todos los tests, localizando ciertos errores en el código nuevo, casi todos relativos al manejo
de los extremos en los intervalos y el cruce de los diversos datos. Solucionados estos errores,
se comprobó el correcto funcionamiento del método, comparando también en algunos casos
con cálculos realizados a mano para asegurar que no existı́an más errores no detectados en
el código antiguo.

5
las compensaciones de horas extra eran entidades abstractas empleadas para compensar a un usua-
rio las horas extra realizadas hasta una fecha concreta, de un modo similar a pagarle lo realizado y
poner a cero su número.
Capı́tulo 6

Creación de interfaces web


dinámicas

El siguiente aspecto a comentar será el conjunto de interfaces web dinámicas desa-


rrolladas para el conjunto de PhpReport. Primero comentaremos de manera general sus
caracterı́sticas, para luego detallar sus objetivos, extendernos en su diseño e implementa-
ción y acabar con las pruebas que se le aplicaron.

6.1. Objetivos y descripción


6.1.1. Objetivos concretos
El trabajo realizado en este apartado perseguı́a las siguientes metas:

Creación de las interfaces dinámicas para PhpReport (aunque no todas las páginas,
por su propia naturaleza, dispongan de elementos realmente dinámicos).

Construcción de los servicios web que permitirán la comunicación de los ((widgets))


dinámicos con el servidor.

6.1.2. Descripción general


PhpReport, como ya se comentó en el apartado 5.1.2 en la página 49, se concibió inicial-
mente como una aplicación de una complejidad de almacenamiento de datos relativamente
pequeña. Por ese motivo las interfaces también eran sencillas, cumpliendo perfectamente su
objetivo y sin ninguna pega por parte del usuario. Pero, según la aplicación fue creciendo,
el usuario disponı́a de un mayor número de funcionalidades que explotar. Esto provocó un
aumento tanto en el número de páginas existentes como en la cantidad de información
mostrada en las que ya existı́an.
Esta concentración de información en ciertas páginas resultó, entre otras cosas, en
que el usuario tuviera que recargarla por completo para poder visualizar nueva información
en cualquier parte de ella, en ocasiones para actualizar una pequeña tabla o incluso un
único valor, o bien para enviar datos a actualizar en la base de datos. La incomodidad que
esto supone (ver apartado 2.2 en la página 4) ha motivado la creación de un conjunto de
interfaces dinámicas AJAX para la totalidad de la aplicación que mejoren sustancialmente
la experiencia del usuario.

61
6.2. Análisis y diseño 62

Dichas interfaces permitirán que los componentes de las páginas se comuniquen de


manera ası́ncrona e independiente con el servidor, permitiendo a la aplicación funcionar de
una forma más dinámica y fluida para el usuario. Ası́, entre otras mejoras, el envı́o de datos
de un formulario o cambios en el contenido de una tabla no requerirán la actualización
de la página completa, sino únicamente la retransmisión de los datos afectados. También
el disponer de ((widgets)) de más alto nivel, como paneles con pestañas o sub-ventanas
flotantes, permitirá la reordenación de las distintas secciones de la aplicación de una manera
más compacta e intuitiva.

6.2. Análisis y diseño


A la hora de elaborar las interfaces se decidió desde el principio que la nueva versión
de la aplicación seguirı́a un desarrollo incremental en lo referente a ellas, por lo que el
objetivo prioritario serı́a crear un conjunto de interfaces dinámicas que proporcionaran las
funcionalidades elementales a fin de tener una aplicación válida para el entorno laboral lo
antes posible.
En cuanto a dichas funcionalidades elementales, la mayorı́a se concentraron en poder
realizar operaciones CRUD sobre todas las entidades manejadas en BD y en trasladar las
capacidades más ampliamente usadas en la versión anterior de PhpReport, además de poder
realizar ambos tipos de planificación (vistas en el capı́tulo 4 en la página 33).

6.2.1. Funcionalidades esenciales


Las caracterı́sticas que se consideraron necesarias para tener una versión de PhpReport
funcional, aunque no tuviera un conjunto exhaustivo de interfaces, fueron:

Operaciones CRUD de las siguientes entidades:

• Task. • Project.
• User.
• Sector.
• User Group.
• Area. • Customer.

• Entradas de los históricos (coste por hora, ciudad, jornada y área) de los usuarios.
• Todos los componentes de ambos tipos de planificación (vistos en el aparta-
do 4.2 en la página 34).

Extracción de informes sobre usuarios:

• Horas extra.
• Vacaciones pendientes.
• Horas trabajadas de un usuario por proyecto y cliente.
• Horas trabajadas por usuario y Story.

Extracción de informes sobre proyectos:


6.3. Implementación 63

• Datos generales del proyecto junto a horas trabajadas y estimadas, facturación y


beneficios, y representaciones porcentuales o relativas de estos datos (desviación
respecto a lo estimado, beneficio por hora, etc.).
• Horas trabajadas por proyecto y cliente.
• Horas trabajadas por proyecto y usuario.

Una vez que se tuvieran estas funcionalidades la aplicación estarı́a en disposición de ser
empleada para gestionar las tareas realizadas, con visos a ser ampliada en el futuro, sobre
todo en lo referente a añadir nuevas interfaces y nuevas acciones que presenten otros tipos
de informes o datos derivados.

6.2.2. Organización de las interfaces


Las interfaces fueron organizadas en base a la entidad o conjunto sobre el que operan,
de manera que se crearon los siguientes conjuntos:

Task: interfaz CRUD de las tareas.

User : interfaces CRUD de User, su relación con User Group y de todos los históricos,
además de la extracción de informes sobre usuarios, información de horas extra y de
vacaciones pendientes.

Customer : interfaces CRUD de Customer y Sector y de su relación.

Project: interfaces CRUD de Project y sus relaciones con Area, Customer y User,
además de la extracción de informes sobre proyectos.

Area: interfaz CRUD de Area.

Planificación: todas las interfaces relacionadas con la planificación.

Además de las interfaces propias de la lógica de negocio se creará una página sencilla
de login para poder autenticarse en la aplicación.
El diseño especı́fico de cada interfaz será comentado en el siguiente apartado sobre
implementación, ya que al emplear el framework ExtJS (apartado 2.3.2 en la página 12)
las interfaces se crearı́an en base a sus widgets. Dichos ((widgets)) poseen un gran número
de opciones de configuración y combinación, por lo que en bastantes ocasiones se cambió el
enfoque de la interfaz durante su implementación al contemplar un nuevo diseño más
cómodo y/o completo (incluso se descubrieron nuevos ((widgets)) de ExtJS, bien porque
fueron introducidos en las versiones más recientes [91] o porque se incluyen como ejemplos
en el código de ExtJS pero no se encuentran documentados en el API oficial).

6.3. Implementación
La implementación de las interfaces se realizó en JavaScript empleando el framework
ExtJS (apartado 2.3.2 en la página 12), el cual nos provee de una serie de widgets, muchos
de los cuales tienen caracterı́sticas AJAX, para combinar a la hora de crear la interfaz web.
6.3. Implementación 64

Aunque las interfaces estén basadas casi totalmente en ese JavaScript, sus ficheros son
realmente PHP, ya que incluyen una pequeña parte de código PHP que es ejecutado pre-
viamente en el lado del servidor. El código JavaScript está presente gracias a las facilidades
de PHP para combinar código del lado del servidor con el código despachado que se ejecuta
en el lado del cliente.
Además de las propias interfaces fue necesario crear servicios web. Éstos son fragmentos
de código en PHP a los cuales se realizan peticiones GET (en ocasiones pasándoles un XML
por su entrada estándar) desde las interfaces con el objetivo de que las interfaces dinámicas
realicen las operaciones CRUD requeridas. De este modo, por ejemplo una tabla puede
llamar a un servicio web pasándole los parámetros de un formulario por la url (petición
GET ), y éste realizará la operación requerida y responderá con un código XML (u otro
lenguaje de marcado) que la tabla parseará internamente para después presentar los datos
de la forma adecuada. Los servicios web requieren que el usuario esté logueado y cuente
con permisos para su uso a través del fichero de configuración.
Ya que la creación de los servicios web estuvo ı́ntimamente ligada a las necesidades que
iban surgiendo en las interfaces, serán nombrados con cada interfaz según éstas se vayan
detallando.
Todas las tablas incluidas en las interfaces emplean dicho ((widget)) de ExtJS, el cual
proporciona capacidades para ocultar columnas de la tabla y ordenar por cualquiera de
ellas en orden creciente o decreciente. Además, dicha configuración se guarda en cookies,
por lo que el usuario podrá seguir viendo la tabla con el mismo navegador tal y como la
configuró la última vez.
Algunas interfaces presentan tablas de estructura dinámica, es decir, que no siempre
presentan las mismas columnas (las más comunes son las tablas que presentan informes).
En estos casos se han aprovechado las capacidades del framework para crear dichas tablas
en base a una estructura pasada por un servicio web en un JSON1 , siendo éstos los únicos
casos en que no se emplea XML.
Antes de detallar cada interfaz señalaremos que todas incluyen cuatro ficheros PHP:

auth.php: este fichero contiene el código encargado de comprobar si el usuario


está autenticado para, en caso contrario, redirigirlo a la página de login (la única
que no requiere estar logueado). También comprueba si el usuario logueado tiene
permisos para acceder a la página, y si no es ası́ le mostrará una etiqueta informativa
sin cargar los demás elementos.

header.php: contiene las cabeceras HTTP, entre las cuales se incluyen las importa-
ciones de código JavaScript y hojas de estilo CSS necesarias.

sidebar.php: añade la barra lateral que contiene los botones para acceder a las
distintas interfaces de PhpReport.

footer.php: los tags finales de HTTP (la autorı́a y los tags que cierran aquellos
abiertos en header.php).
1
ExtJS tiene previsto dar soporte próximamente para manejar tablas dinámicas con XML, por lo
que si se considerará apropiado se podrı́a unificar el formato de intercambio de datos.
6.3. Implementación 65

Figura 6.1: barra lateral de la interfaz web de PhpReport

6.3.1. Interfaces en torno a Task


Se creó una única interfaz dentro del conjunto relacionado con las tareas, la destinada
a las operaciones CRUD sobre las tareas personales de cada usuario.

Interfaz CRUD de Task


Es la interfaz empleada para introducir, ver, modificar y eliminar las tareas personales de
cada usuario (en la imagen 6.2 en la página siguiente podemos ver una captura de pantalla).
Consta para cada tarea de un panel con un formulario individual, el cual incluye los campos
correspondientes a sus atributos:
Time: son comboboxes especı́ficos para horas (intervalo cerrado-abierto), los cuales
permiten entradas tanto en formato HH:mm como HHmm, y con entradas por defecto
con incrementos de 15 minutos. Los campos incluyen código validador en JavaScript
que comprueba en el lado del usuario la coherencia entre ambos valores (inicio < fin).

Customer : sus posibles valores son recuperados mediante el servicio web getUserCus-
tomersService, y presenta capacidades ((type-ahead)) (filtra las entradas del combobox
en base a lo escrito por el usuario, pudiendo completar automáticamente el texto in-
troducido). No permite valores no devueltos por el servicio.

Project: sus posibles valores son recuperados mediante el servicio web getCustomer-
ProjectsService en base a la entrada del campo de cliente, y presenta capacidades
((type-ahead)). No permite valores no devueltos por el servicio.

Task type: sus posibles valores están incrustados en el código de la interfaz, y presenta
capacidades ((type-ahead)). No permite valores no devueltos por el servicio.

Story : campo de texto sin ninguna limitación.

Task Story : sus posibles valores son recuperados mediante el servicio web getOpen-
TaskStoriesService en base a la entrada del campo de proyecto, y presenta capacidades
((type-ahead)). No permite valores no devueltos por el servicio.

Telework: checkbox sin ningún añadido.

Description: campo de texto multilı́nea sin limitaciones especiales.


También incluyen dos botones:
6.3. Implementación 66

Figura 6.2: interfaz web de PhpReport para las operaciones CRUD sobre las tareas
6.3. Implementación 67

Delete: borra el panel de la tarea actual, y si existı́a en BD la marca para borrarla


posteriormente de ahı́.

Clone: crea un panel nuevo con los datos de la tarea actual.

Además presentan un pequeño botón en la parte superior derecha que permite colapsar
el panel para facilitar la ocultación de las tareas que no nos interesan.
Debajo de todos los paneles se hallan un botón, New Task, que añade un panel nuevo
para anotar una tarea adicional, y el botón Save que nos permite almacenar los cambios
realizados desde la última vez que salvamos. Para ello se emplean tres servicios web: create-
TasksService, updateTasksService y deleteTasksService. Las tareas se obtienen inicialmente
gracias a otro servicio web, getUserTasksService.
En la figura 6.3 en la página siguiente incluimos un diagrama de secuencia con todo los
pasos por los que atraviesa el proceso de salvado de las tareas de un usuario, para poder
ver comprender mejor el uso de los web services CRUD.
Aparte de los elementos centrales de la página se incluyen cuatro ((widgets)) adicionales
en la barra lateral, debajo del menú principal:

Calendario: en él se elige el dı́a del cual se quiere gestionar la anotación de tareas.

Clonación de dı́as: nos permite elegir otro dı́a del calendario para copiar de él todas
las tareas e incluirlas en el actual.

Resumen de trabajo: indica el número de horas trabajadas por el usuario el dı́a selec-
cionado, su semana y su mes, obteniéndolas mediante el servicio getPersonnalSum-
maryByDateService.

Expansión/colapso general: permite expandir y colapsar simultáneamente todas las


tareas de la página actual.

La interfaz emplea los siguientes servicios web:

getUserTasksService: devuelve las tareas de un usuario en una fecha.

getUserCustomersService: devuelve los clientes actuales de un usuario.

getCustomerProjectsService: devuelve los proyectos actuales de un cliente.

getOpenTaskStoriesService: devuelve las Task Stories activas (sin fecha de fin) ac-
tualmente para un proyecto y asignadas al usuario actualmente logueado.

getPersonnalSummaryByDateService: devuelve las horas trabajadas por un usuario


en un dı́a, su mes y su semana.

createTasksService: crea en BD las tareas pasadas por XML.

updateTasksService: actualiza en BD las tareas pasadas por XML.

deleteTasksService: elimina de BD las tareas pasadas por XML.


6.3. Implementación 68

Figura 6.3: diagrama UML de secuencia del proceso completo de salvado de las tareas de un
usuario
6.3. Implementación 69

6.3.2. Interfaces en torno a User


Son las interfaces relacionadas con la gestión de los usuarios y la obtención de informes
sobre ellos.

Página personal
Es la interfaz en la cual un usuario puede consultar fácilmente datos sobre su cuenta
(login y grupos de usuario) y una tabla con un informe con las horas trabajadas por proyecto
y cliente entre dos fechas (imagen 6.4 en la página siguiente). Para introducir dichas fechas
se dispone de un pequeño formulario con campos para ambas (intervalo cerrado-cerrado).
La interfaz emplea los siguientes servicios web:
getUserProjectCustomerReportJsonService: devuelve un informe con las horas de tra-
bajo de un usuario para cada proyecto y cliente entre dos fechas.

Evaluación de usuarios
Es la interfaz en la cual se puede obtener en una tabla el informe de horas trabajadas por
usuario y Story entre dos fechas (imagen 6.5 en la página 71). Para introducir dichas fechas
se dispone de un pequeño formulario con campos para ambas (intervalo cerrado-cerrado).
La interfaz emplea los siguientes servicios web:
getUserStoryReportJsonService: devuelve un informe con las horas de trabajo por
cada usuario y Story entre dos fechas.

Informe de resultados de las horas de trabajo


Es la interfaz en la cual se puede obtener en una tabla el informe de horas extra y
vacaciones pendientes de los usuarios entre dos fechas (imagen 6.6 en la página 72). Para
introducir dichas fechas se dispone de un pequeño formulario con campos para ambas (in-
tervalo cerrado-cerrado).

La interfaz emplea los siguientes servicios web:


getExtraHoursReportService: devuelve un informe con las horas extra de cada usuario.
getPendingHolidayHoursService: devuelve un informe con las horas de vacaciones
pendientes de cada usuario.

Gestión de usuarios
Es la interfaz CRUD para los usuarios y sus históricos (imagen 6.7 en la página 75).
En el panel superior se pueden crear, eliminar o editar usuarios y asignar o desasignar a
los grupos de usuarios configurados en el archivo de configuración2 . El panel superior es
2
se incluye una entrada listándolos debido a ciertos problemas que ya presentaba PhpReport al
recuperarlos del Lightweight Directory Access Protocol (LDAP), ya que se manejan distintos tipos de
grupos de usuarios que no pueden ser diferenciados más que por su nombre, y tampoco se pueden
eliminar o modificar debido a que otras aplicaciones dependen de ellos.
6.3. Implementación 70

Figura 6.4: interfaz web de PhpReport con los detalles de usuario


6.3. Implementación 71

Figura 6.5: interfaz web de PhpReport para evaluación de los usuarios


6.3. Implementación 72

Figura 6.6: interfaz web de PhpReport para la obtención del informe de horas extra y vacaciones
pendientes de los usuarios
6.3. Implementación 73

el encargado de la gestión de los propios usuarios, mientras que el inferior permite la ges-
tión de los históricos del usuario seleccionado en el primero (sólo carga los datos cuando el
panel se encuentra expandido). Ambas tablas permiten la edición en lı́nea de sus elementos.

La interfaz emplea los siguientes servicios web:

getAllUsersService: devuelve los datos de todos los usuarios.

createUsersService: crea en BD los usuarios pasados por XML.

updateUsersService: actualiza en BD los usuarios pasados por XML.

deleteUsersService: elimina de BD los usuarios pasados por XML.

getUserHourCostHistoriesService: devuelve las entradas del histórico de coste por


hora de un usuario.

createHourCostHistoriesService: crea en BD las entradas del histórico de coste por


hora pasadas por XML.

updateHourCostHistoriesService: actualiza en BD las entradas del histórico de coste


por hora pasadas por XML.

deleteHourCostHistoriesService: elimina de BD las entradas del histórico de coste por


hora pasadas por XML.

getUserCityHistoriesService: devuelve las entradas del histórico de coste por hora de


un usuario.

createCityHistoriesService: crea en BD las entradas del histórico de ciudad pasadas


por XML.

updateCityHistoriesService: actualiza en BD las entradas del histórico de ciudad pa-


sadas por XML.

deleteCityHistoriesService: elimina de BD las entradas del histórico de ciudad pasadas


por XML.

getUserJourneyHistoriesService: devuelve las entradas del histórico de jornada de un


usuario.

createJourneyHistoriesService: crea en BD las entradas del histórico de jornada pa-


sadas por XML.

updateJourneyHistoriesService: actualiza en BD las entradas del histórico de jornada


pasadas por XML.

deleteJourneyHistoriesService: elimina de BD las entradas del histórico de jornada


pasadas por XML.

getUserAreaHistoriesService: devuelve las entradas del histórico de área de un usuario.


6.3. Implementación 74

createAreaHistoriesService: crea en BD las entradas del histórico de área pasadas por


XML.

updateAreaHistoriesService: actualiza en BD las entradas del histórico de área pasa-


das por XML.

deleteAreaHistoriesService: elimina de BD las entradas del histórico de área pasadas


por XML.

6.3.3. Interfaces en torno a Customer


Recoge las interfaces para la gestión de los clientes y sus sectores.

Gestión de clientes y sectores


Es la interfaz CRUD para los clientes y sus sectores (ver figura 6.8 en la página 76). En
el panel superior se pueden crear, editar o eliminar clientes, y en el inferior los sectores. La
tabla de clientes contiene un botón que permite abrir la dirección web asociada al cliente
seleccionado. Ambas tablas permiten la edición en lı́nea de sus elementos.

La interfaz emplea los siguientes servicios web:

getAllSectorsService: devuelve los datos de todos los sectores.

createSectorsService: crea en BD los sectores pasados por XML.

updateSectorsService: actualiza en BD los sectores pasados por XML.

deleteSectorsService: elimina de BD los sectores pasados por XML.

getUserCustomersService: devuelve los datos de todos los clientes (aunque el servicio


permite un mayor abanico de peticiones).

createCustomersService: crea en BD los clientes pasados por XML.

updateCustomersService: actualiza en BD los clientes pasados por XML.

deleteCustomersService: elimina de BD los clientes pasados por XML.

6.3.4. Interfaces en torno a Area


Gestión de áreas
Es la interfaz CRUD para las áreas (figura 6.9 en la página 78). En el panel se pueden
crear, editar o eliminar áreas. La tabla permite la edición en lı́nea de sus elementos.

La interfaz emplea los siguientes servicios web:

getAllAreasService: devuelve los datos de todas las áreas.


6.3. Implementación 75

Figura 6.7: interfaz web de PhpReport para la gestión de los usuarios y sus históricos
6.3. Implementación 76

Figura 6.8: interfaz web de PhpReport para la gestión de los clientes y sus sectores
6.3. Implementación 77

createAreasService: crea en BD las áreas pasadas por XML.

updateAreasService: actualiza en BD las áreas pasadas por XML.

deleteAreasService: elimina de BD las áreas pasadas por XML.

6.3.5. Interfaces en torno a Project


Gestión de proyectos
Es la interfaz CRUD para los proyectos (ver figura 6.10 en la página 79). En el panel
se pueden crear, editar o eliminar áreas. Debido a que los proyectos presentan un número
importante de parámetros, su edición y creación se realiza en una ventana emergente de
la propia interfaz. Además incluye dos botones en la parte inferior que permiten asignar y
desasignar usuarios (relación ProjectUser ) y clientes (relación Requests) mediante sencillas
interfaces Drag & Drop. Haciendo doble clic en la fila de un proyecto accedemos a la página
con sus detalles.

La interfaz emplea los siguientes servicios web:


assignUsersToProjectService: asigna usuarios a un proyecto, ambos datos pasados en
un XML.

assignCustomersToProjectService: asigna clientes a un proyecto, ambos datos pasados


en un XML.

deassignUsersFromProjectService: asigna usuarios a un proyecto, ambos datos pasa-


dos en un XML.

deassignCustomersFromProjectService: asigna clientes a un proyecto, ambos datos


pasados en un XML.

getProjectUsersService: devuelve los datos de los usuarios asociados a un proyecto.

getProjectCustomersService: devuelve los datos de los clientes asociados a un pro-


yecto.

getTodayAreaUsersService: devuelve los datos de todos los usuarios de la misma área


que un proyecto en la fecha actual.

getAllUsersService: devuelve los datos de todos los usuarios.

getAllCustomersService: devuelve los datos de todos los clientes.

getAllProjectsService: devuelve los datos de todos los proyectos.

createProjectsService: crea en BD los proyectos pasados por XML.

updateProjectsService: actualiza en BD los proyectos pasados por XML.

deleteProjectsService: elimina de BD los proyectos pasados por XML.


6.3. Implementación 78

Figura 6.9: interfaz web de PhpReport para la gestión de las áreas


6.3. Implementación 79

Figura 6.10: interfaz web de PhpReport para la gestión de los proyectos


6.3. Implementación 80

Detalles de proyecto
Es la interfaz que nos presenta los detalles de un proyecto, tanto sus atributos como
otros datos derivados e informes User-Story y User-Customer para el proyecto (ver ima-
gen 6.11 en la página siguiente). Existe un formulario con campos para las fechas de inicio
y fin lı́mites de los informes, aunque al cargar la página ya nos mostrará el informe con
todas las horas hasta la fecha actual.

La interfaz emplea los siguientes servicios web:


getProjectUserStoryReportJsonService: devuelve un informe con las horas de trabajo
para un proyecto por cada usuario y Story entre dos fechas.
getProjectUserCustomerReportJsonService: devuelve un informe con las horas de tra-
bajo para un proyecto por cada usuario y Story entre dos fechas.

Evaluación de proyectos
Esta interfaz presenta una tabla que nos muestra los datos económicos (facturación,
facturación por hora, etc.) y de trabajo (horas trabajadas, horas estimadas, desviación,
etc.) para todos los proyectos (figura 6.12 en la página 82). Incluye un botón en la parte
inferior que nos sirve para filtrar los proyectos y presentar sólo aquéllos actualmente activos.

La interfaz emplea los siguientes servicios web:


getAllCustomProjectsService: devuelve un informe con datos de trabajo y económicos
para todos los proyectos.

Resumen de proyectos
Esta interfaz permite obtener los informes de horas de trabajo Project-User y Project-
Customer para todos los proyectos (imagen 6.13 en la página 83). Cada uno se presenta
en una pestaña diferente en el mismo panel.

La interfaz emplea los siguientes servicios web:


getProjectCustomerReportJsonService: devuelve un informe con las horas de trabajo
por cada proyecto y cliente entre dos fechas.
getProjectUserReportJsonService: devuelve un informe con las horas de trabajo por
cada proyecto y usuario entre dos fechas.

6.3.6. Interfaces para la planificación


Resumen de planificación a corto plazo (XP Tracker Summary )
Esta interfaz nos muestra la planificación a corto plazo existente para los proyectos
activos en los cuales está asignado el usuario logueado actualmente en el sistema (ima-
gen 6.14 en la página 85). Por cada uno de dichos proyectos mostrará un panel con un
6.3. Implementación 81

Figura 6.11: interfaz web de PhpReport para ver detalles de los proyectos
6.3. Implementación 82

Figura 6.12: interfaz web de PhpReport de evaluación de proyectos


6.3. Implementación 83

Figura 6.13: interfaz web de PhpReport de resumen de proyectos


6.3. Implementación 84

árbol, el cual nos muestra los elementos integrantes de la planificación respetando su je-
rarquı́a: Iteration, Story y Task Story (apartado 4.2.1 en la página 35). De sus datos se
muestran los habitualmente útiles, a quién se ha asignado, las fechas de inicio y fin y las
horas de trabajo estimadas, realizadas y pendientes (no todos los elementos de la jerarquı́a
del árbol incluyen estos campos, y en tal caso simplemente se mostrarán vacı́os). Al ha-
cer doble clic en una Iteration o Story nos llevará a su página de detalles, mientras que
una Task Story nos redirige a los detalles de su Story, ya que son manejadas en su mis-
ma interfaz. El árbol es el encargado de permitir la creación de nuevos elementos para la
planificación, existiendo en su barra inferior una serie de botones que nos permitirán crear
el primer elemento de una planificación o bien elementos hermanos o hijos de aquél que
esté seleccionado.
En las Task Story se emplea un código de colores en su fondo para identificar el estado
de su trabajo: verde nos indicará que el trabajo está terminado, rojo que todavı́a no ha
empezado y amarillo que se encuentra en progreso.
Esta interfaz emplea actualmente un único servicio web3 :

getProjectTrackerTree: devuelve un json con la estructura del árbol de planificación


a corto plazo para un proyecto.

Detalles de Iteration
Esta interfaz nos presenta en un panel los datos actuales de una Iteration (ver figu-
ra 6.15 en la página 86), con un botón en la esquina superior derecha que nos permite
editarla llevándonos a su formulario. En la parte inferior presenta otro panel que incluye el
árbol de su proyecto, con la rama de la Iteration expandida para que podamos ver las Story
que contiene.
Solamente emplea el servicio web para recuperar el árbol:

getProjectTrackerTree: devuelve un json con la estructura del árbol de planificación


a corto plazo para un proyecto.

Formulario de Iteration
Es el formulario empleado para crear y editar Iteration, conteniendo campos para sus
atributos (ver figura 6.16 en la página 87).
No tiene ningún elemento destacable y tampoco emplea servicios web.
3
los formularios de creación y edición de los elementos de planificación no se encuentran actualmente
con un enfoque dinámico debido a ciertas complicaciones que presenta el ((widget)) del árbol de ExtJS,
el cual acaba de salir de su fase experimental, que hacen actualmente inviable el uso de ventanas
interiores en esta misma interfaz; en todo caso, se espera que el problema se solucione en versiones
próximas del framework, lo que motivará la adopción del mismo enfoque de formularios dinámicos que
otras interfaces.
6.3. Implementación 85

Figura 6.14: interfaz web de PhpReport de resumen de planificación a corto plazo


6.3. Implementación 86

Figura 6.15: interfaz web de PhpReport de detalles de Iteration


6.3. Implementación 87

Figura 6.16: interfaz web de PhpReport del formulario de Iteration


6.3. Implementación 88

Detalles de Story
Esta interfaz nos presenta en un panel los datos actuales de una Story (ver figu-
ra 6.17 en la página siguiente), además de ciertos datos derivados de las horas trabajadas,
incluyendo un botón en la esquina superior derecha que nos permite editarla llevándonos
a su formulario. Debajo presenta un panel con las Task Story que contiene, con botones
para crear, editar y eliminar, empleando para ello ventanas interiores a esta propia interfaz.
Por último contiene un panel que nos muestra la descripción de todas las tareas asociadas
a sus Task Story a modo de descripción de la Story.
Emplea los siguientes servicios web:

getStoryCustomTaskStoriesService: devuelve las Task Story asociadas a una Story.

createTaskStoriesService: crea en BD las entradas de Task Story pasadas por XML.

updateTaskStoriesService: actualiza en BD las entradas de Task Story pasadas por


XML.

deleteTaskStoriesService: elimina de BD las entradas de Task Story pasadas por XML.

Formulario de Story
Es el formulario empleado para crear y editar Story (ver imagen 6.18 en la página 90),
conteniendo campos para sus atributos.
Al igual que el de iteraciones, tampoco emplea servicios web, y solamente destacaremos
que por defecto se selecciona al usuario actual como supervisor en caso de que sea una
opción disponible en el combobox correspondiente, ya que es habitual que sea él el encargado
de crear las Story.

Resumen de planificación a largo plazo (Analysis Tracker Summary )


Interfaz análoga a la empleada con la planificación a corto plazo (vista en el aparta-
do 6.3.6 en la página 80), en la cual simplemente cambian las entidades manejadas, que
serán las correspondientes a largo plazo (Module, Section y Task Section), y que no se em-
plea el ćodigo de colores para indicar el estado del trabajo. En la imagen 6.19 en la página 91
podemos observar su aspecto.
Esta interfaz, al igual que en la planificación a corto plazo, emplea actualmente un único
servicio web4 :

getProjectAnalysisTrackerTree: devuelve un json con la estructura del árbol de plani-


ficación a largo plazo para un proyecto.

4
de nuevo sus formularios son estáticos por el momento, pero se espera migrarlos a un conjunto
dinámico cuando el problema del ((widget)) del árbol esté solucionado.
6.3. Implementación 89

Figura 6.17: interfaz web de PhpReport de detalles de Story


6.3. Implementación 90

Figura 6.18: interfaz web de PhpReport del formulario de Story


6.3. Implementación 91

Figura 6.19: interfaz web de PhpReport de resumen de planificación a largo plazo


6.3. Implementación 92

Detalles de Module
Esta interfaz nos presenta en un panel los datos actuales de un Module (ver figu-
ra 6.20 en la página siguiente), con un botón en la esquina superior derecha que nos permite
editarla llevándonos a su formulario. En la parte inferior presenta otro panel que incluye el
árbol de su proyecto, con la rama del Module expandida para que podamos ver las Section
que contiene.
Solamente emplea el servicio web para recuperar el árbol:

getProjectAnalysisTrackerTree: devuelve un json con la estructura del árbol de plani-


ficación a largo plazo para un proyecto.

Formulario de Module
Es el formulario empleado para crear y editar Module, conteniendo campos para sus
atributos (ver figura 6.21 en la página 94).
No tiene ningún elemento destacable y tampoco emplea servicios web.

Detalles de Section
Esta interfaz nos presenta en un panel los datos actuales de una Section (ver figu-
ra 6.22 en la página 95), además de ciertos datos derivados de las horas trabajadas, inclu-
yendo un botón en la esquina superior derecha que nos permite editarla llevándonos a su
formulario. Debajo presenta un panel con las Task Section que contiene, con botones para
crear, editar y eliminar, empleando para ello ventanas interiores a esta propia interfaz.
Emplea los siguientes servicios web:

getSectionCustomTaskSectionsService: devuelve las Task Section asociadas a una


Section.

createTaskSectionService: crea en BD las entradas de Task Section pasadas por XML.

updateTaskSectionsService: actualiza en BD las entradas de Task Section pasadas


por XML.

deleteTaskSectionsService: elimina de BD las entradas de Task Section pasadas por


XML.

Formulario de Section
Es el formulario empleado para crear y editar Section, conteniendo campos para sus
atributos (imagen 6.23 en la página 96).
Al igual que el de módulos, tampoco emplea servicios web, y solamente destacaremos
que por defecto se selecciona al usuario actual como supervisor en caso de que sea una
opción disponible en el combobox correspondiente, ya que es habitual que sea él el encargado
de crear las Sections.
6.3. Implementación 93

Figura 6.20: interfaz web de PhpReport de detalles de Module


6.3. Implementación 94

Figura 6.21: interfaz web de PhpReport del formulario de Module


6.3. Implementación 95

Figura 6.22: interfaz web de PhpReport de detalles de Section


6.3. Implementación 96

Figura 6.23: interfaz web de PhpReport del formulario de Section


6.4. Pruebas y resultados obtenidos 97

6.4. Pruebas y resultados obtenidos


Las pruebas sobre las interfaces web se realizaron en dos pasos:
1. Creación de pruebas formales.
2. Puesta en producción de una versión de prueba junto con un ((bug tracker)).

6.4.1. Pruebas formales


Se creó un conjunto de pruebas formales sobre las interfaces que comprueban principal-
mente el correcto funcionamiento de las capacidades CRUD y de la extracción de informes5 .
Para ello se empleó el framework Selenium (visto en el apartado 2.3.2 en la página 18), con
el cual se guardaron los tests en formato XML, ejecutándose con el mismo framework. Se
realizaron tests para todas las interfaces a excepción de las que incluı́an simplemente un
formulario estático, ya que una de las primeras mejoras serı́a convertirlas en una interfaz
de ventanas dinámicas en cuanto el ((widget)) del árbol de ExtJS deje de estar en estado
experimental, además de por su extrema simplicidad sin uso de servicios web.
Las pruebas están pensadas para ser ejecutadas con un estado concreto de la BD, no
con el objetivo de obtener siempre los mismos datos (aunque sı́ se comprueban algunos
en las interfaces CRUD), sino para evitar conflictos en las entidades, poder realizar login
y efectuar cambios de grupo. Además, ExtJS asigna ids a los elementos según el orden en
que los renderiza, por lo que un cambio en su número sobre el previsto en el momento de
crear los tests provocarı́a un mal funcionamiento. Por todo esto se proporciona un ((dump))
de la BD de PotsgreSQL tal y como se encontraba en el momento de terminar los tests y
pasándolos todos ellos.
Debemos tener siempre en cuenta que estos tests, aunque son formales, no son uni-
tarios (ya que Selenium no proporciona esas capacidades, como ya se comentó en el apar-
tado 2.3.2 en la página 18). Esto implica que el fallo de alguno de ellos puede dejar la BD
en un estado inconsistente o inválido, al menos para repetir su propia ejecución.

Los tests creados fueron concretamente los siguientes:

loginTest: comprueba que se realiza login correctamente en el sistema y que se crea


la cookie correspondiente.
tasksTest: comprueba las funcionalidades CRUD de usuarios en su interfaz.
userDetailsTest: comprueba que la página de detalles del usuario muestra los
((widgets)) con los datos adecuados.
usersManagementTest: comprueba las funcionalidades CRUD de usuarios en su in-
terfaz.
hourCostHistoriesManagementTest: comprueba las funcionalidades CRUD del his-
tórico de coste por hora en la interfaz de usuarios.
5
el objetivo de las pruebas a este nivel no es comprobar que el contenido de los informes es correcto,
ámbito correspondiente a la capa modelo (apartado 5.4 en la página 59), sino que la interfaz muestra
una tabla que incluye los campos adecuados.
6.4. Pruebas y resultados obtenidos 98

journeyHistoriesManagementTest: comprueba las funcionalidades CRUD del his-


tórico de jornada en la interfaz de usuarios.

areaHistoriesManagementTest: comprueba las funcionalidades CRUD del históri-


co de área en la interfaz de usuarios.

cityHistoriesManagementTest: comprueba las funcionalidades CRUD del históri-


co de ciudad en la interfaz de usuarios.

extraHoursReportTest: comprueba que la página con el informe de horas extra


muestra los ((widgets)) con los datos adecuados.

usersEvaluationTest: comprueba que la página de evaluación de usuarios muestra


los ((widgets)) con los datos adecuados.

areasManagementTest: comprueba las funcionalidades CRUD de áreas en su inter-


faz.

sectorsManagementTest: comprueba las funcionalidades CRUD de sectores en la


interfaz de clientes.

clientsManagementTest: comprueba las funcionalidades CRUD de clientes en su


interfaz.

projectsManagementTest: comprueba las funcionalidades CRUD de proyectos en


su interfaz.

assignProjectClientsTest: comprueba la funcionalidad de asignación de clientes


a proyectos en su interfaz.

assignProjectUsersTest: comprueba la funcionalidad de asignación de usuarios a


proyectos en su interfaz.

projectsEvaluationTest: comprueba que la página de evaluación de proyectos


muestra los ((widgets)) con los datos adecuados.

projectsSummaryTest: comprueba que la página de resumen de proyectos muestra


los ((widgets)) con los datos adecuados.

taskSectionsManagementTest: comprueba las funcionalidades CRUD de taskSec-


tion en la interfaz de section.

taskStoriesManagementTest: comprueba las funcionalidades CRUD de taskStory


en la interfaz de story.

También se incluyen las siguientes suites para aglutinar tests:

allTestsSuite: contiene todos los tests.

wholeClientsManagementSuite: contiene los tests de la interfaz de clientes.

wholeUsersManagementSuite: contiene los tests de la interfaz de usuarios.


6.4. Pruebas y resultados obtenidos 99

wholeProjectsManagementSuite: contiene los tests de la interfaz de proyectos.

En cuanto a la ejecución de los tests, se recomiendan las siguientes pautas debido al


manejo de múltiples ((widgets)) dinámicos:

Elegir una velocidad de ejecución media/baja en la interfaz de Selenium.

No tocar durante su ejecución ningún elemento de la página que se está testeando (un
orden diferente en la renderización de los elementos asignará identificadores diferentes
y trastocará la ejecución de los tests).

En el caso del test de la interfaz de tareas, dejar la ventana de Selenium en primer


plano y no ejecutar acciones con el ordenador, ya que en cierto momento se reali-
zará foco sobre la ventana del navegador para que un ((widget)) reconozca la posición
del cursor.

En caso de que algún test falle, realizarlo de manera individual, ya que siempre cabe
la posibilidad de que un mensaje se haya perdido en un paso intermedio (recordemos
que es posible que la BD haya quedado en un estado inconsistente y sea necesario
limpiarla o reiniciarla con el ((dump))).

6.4.2. Versión de pruebas


Una vez que se dispuso de las pruebas formales para comprobar el correcto funciona-
miento del código en todo momento, se procedió a poner en funcionamiento una versión de
prueba en un servidor de la empresa. A la versión de prueba simplemente se le añadió un
pequeño banner encima del menú lateral para avisar que no se trataba de una versión
en producción, a fin de evitar confusiones, siendo por lo demás exactamente igual que lo
comentado hasta ahora.
Junto con la versión de prueba se habilitó un ((bug tracker)) para el proyecto [92],
empleando Trac (comentado en el apartado 2.3.3 en la página 20), el cual proporciona un
sistema de seguimiento de errores y mejoras muy similar al conocido Bugzilla [93], al que
añade capacidades de wiki.
Gracias al feedback obtenido de los miembros de la empresa mediante la combinación
de la versión de prueba y el ((bug tracker)) se pudieron localizar algunos bugs (la mayorı́a
consistentes en errores de escritura o actualización de datos) y sobre todo obtener múlti-
ples sugerencias para mejorar la aplicación. Dichas sugerencias se tuvieron en consideración
siempre que eran aplicables al programa, consistentes la mayorı́a en cambiar la presenta-
ción o formato de los datos, introducir nuevos ((widgets)) que mostraran más información
o automatizar la escritura de algunos campos (e.g. introducir la fecha o usuario actual
directamente).
Debido a la naturaleza en continua espiral de este proceso, las mejoras que resultaran
importantes ya fueron comentadas directamente en el apartado de implementación, por lo
que no volveremos a hablar en detalle sobre ellas.
Capı́tulo 7

Limitaciones, mejoras
potenciales y conclusiones
globales

En este último capı́tulo comentaremos aquellos apartados de PhpReport que por el


momento no han logrado todo su potencial posible, algunas maneras de alcanzarlo en el
futuro y los resultados generales tanto del proceso como del propio producto.

7.1. Limitaciones
7.1.1. Planificación de trabajo
En este apartado no se han apreciado limitaciones sobre los objetivos previstos ini-
cialmente, debido principalmente a que estuvo altamente centrado en el análisis y diseño
partiendo del modelo de XPTracker (ver apartado 4.2 en la página 34), sin encontrar ningún
problema destacable en la implementación o dilemas de diseño.

7.1.2. Extracción de datos avanzada


El rendimiento en tiempo en la extracción de informes es el principal problema
relacionado con este apartado. Este problema se pone de manifiesto cuando el número de
datos almacenados en la BD es de una entidad importante (del orden de varias decenas
de miles de tareas almacenadas1 ) y, sumado al tiempo de renderizado de la tabla en las
interfaces, puede suponer una molestia para los trabajadores, o incluso un impedimento
para su uso.
Esto se debe a que algunas tareas de cruce de datos se realizan en el código y no en
consultas SQL, lo cual permite tener DAOs mucho más limpios (está claramente limitado
en cada uno sobre qué entidades trabajan) pero de un rendimiento menor.

7.1.3. Creación de interfaces web dinámicas


El principal problema que se ha encontrado es que ciertos elementos de ExtJS no
son renderizados correctamente en algunos navegadores (la aplicación se ha probado en
1
en Igalia se han almacenado en PhpReport más de 140.000 tareas desde 2003.

100
7.2. Mejoras potenciales 101

navegadores Firefox y derivados de WebKit [94]), pero en cada versión nueva del framework
solucionan los problemas encontrados, por lo que tampoco se considera crı́tica.

7.2. Mejoras potenciales


7.2.1. Planificación de trabajo
En este apartado se considera como principal mejora destacable el soporte para con-
tenido gráfico o multimedia, ya que durante la planificación del trabajo es habitual querer
compartir con otros miembros cierto contenido más allá del mero texto plano (e.g. gráficas
de diseño). Por ello serı́a interesante dotar a la aplicación de soporte de almacenamien-
to o referencia de contenido multimedia (este último caso realmente concierne más a las
interfaces web, y podrı́a ser incluir un enlace a un wiki asociado con la planificación actual).

7.2.2. Extracción de datos avanzada


Los siguientes puntos se consideran las mejoras más interesantes para esta sección:

Delegar más operaciones en BD: la mejor manera de solucionar el problema comenta-


do en el apartado 7.1.2 en la página anterior serı́a que operaciones realizadas en las
acciones descendieran y se realizaran directamente en BD, con lo cual necesitarı́amos
realizar menos consultas y además las propias operaciones serı́an más rápidas. Por lo
tanto, se propone revisar las acciones y analizar en qué casos se puede bajar código
para que los DAOs lo ejecuten en su SQL sin que éstos dejen de tener un código
razonablemente limpio.

Ampliar las capacidades de obtención de informes genéricos: aunque por el momento


no se han visto necesarios más informes de los que se pueden generar actualmente,
podrı́a ser útil en el futuro el posibilitar la extracción de más tipos, tanto en lo que
respecta a más filtros en los informes de tareas como a obtener informes centra-
dos en otras tablas. Serı́a necesario efectuar un pequeño estudio sobre la utilidad e
importancia de los distintos datos para priorizar su obtención.

7.2.3. Creación de interfaces web dinámicas


Destacamos los siguientes aspectos como las mejoras potenciales más importantes en
las interfaces web:

Interfaces web totalmente dinámicas para planificación: una vez que el ((widget)) para
representar árboles en ExtJS deje de estar en estado experimental y pase a estable
se deberı́a crear un conjunto de interfaces dinámicas con ventanas embebidas que
permitieran añadir, eliminar y editar componentes desde la propia interfaz del árbol,
agilizando su uso.

Mejorar el aspecto de todas las páginas con CSS: debido a que el objetivo del proyecto
era obtener las funcionalidades lo antes posible, el aspecto estético del conjunto pasó a
un segundo plano, proporcionando un aspecto espartano en ese sentido en la mayorı́a
7.3. Conclusiones globales 102

de las páginas. Crear un conjunto de hojas de estilo para lograr un aspecto más
agradable en el diseño de la página como contenedor serı́a deseable.

Renderizar las tablas vacı́as en un primer momento: las tablas de la mayorı́a de


los informes son renderizadas en el momento en que se reciben los datos, lo cual
unido al problema comentado en el apartado 7.1.2 en la página 100 puede provocar
la sensación de que la página se encuentra vacı́a y no va a presentar nada debido
a algún fallo, cuando simplemente está esperando por el XML o JSON. La solución
serı́a renderizar la tabla vacı́a en primer lugar y luego realizar la petición de los datos
reales, mostrando un icono de carga en la tabla para que el usuario sea consciente de
su estado real.

Unificar los ((banners)) de resultado en la interfaz de tareas: los servicios web para
operaciones de creación, edición y borrado generan banners diferentes en la interfaz
de tareas aunque las llamadas a los tres se efectúan pulsando un mismo botón. Esto
es confuso para el usuario si no conoce el funcionamiento interno de la aplicación,
por lo que serı́a aconsejable juntar de algún modo los mensajes de los tres, o cuando
menos diferenciarlos claramente.

Ordenar en el tiempo las operaciones en la interfaz de tareas: los servicios web para
operaciones de creación, edición y borrado de las tareas son llamados con peticiones
enviadas simultáneamente, lo que provoca que su orden de ejecución sea indetermi-
nado. El orden deberı́a ser:

1. Borrado. 2. Edición. 3. Creación.

De este modo eliminamos problemas como que creemos una tarea nueva que en
principio esté solapada con otra, desplacemos esta última en el tiempo y aún ası́ nos
dé error de solapamiento (ya que ha intentado ejecutar antes la creación que la
edición).

7.3. Conclusiones globales


Podemos concluir que PhpReport en su nueva versión ha alcanzado los objetivos pre-
vistos inicialmente:

Ha incorporado correctamente las capacidades de planificación, sin limitaciones sobre


el diseño inicial, proporcionando unas funcionalidades completas, entre las cuales
solamente se sugiere añadir soporte para contenido gráfico y multimedia.

La obtención de informes gracias a las capacidades de data-mining también ha logra-


do cubrir todas las necesidades, aportando además una interfaz con capacidades lo
suficiente generales como para permitir tanto una obtención sencilla de otros infor-
mes como su ampliación, presentando el único inconveniente de un rendimiento en
tiempo alejado poco optimizado cuando se tratan conjuntos de datos de un tamaño
importante en BD.,
7.3. Conclusiones globales 103

Las interfaces web también lograron los objetivos previstos inicialmente, con la ex-
cepción de las destinadas a la planificación, que por el momento emplean en su
mayorı́a formularios estáticos a la espera de que el ((widget)) del árbol de ExtJS pase
a ser estable. También son el apartado susceptible a un mayor número de mejoras,
principalmente por ser del cual se recibe más ((feedback)) de parte de los usuarios
(apartado 6.4.2 en la página 99) ya que es el único que realmente llegan a conocer.

Consecuentemente se puede afirmar que el producto obtenido satisface todas las nece-
sidades iniciales, con la excepción de los formularios estáticos empleados como una solución
temporal.
En cuanto al proceso en sı́, el trabajo se desarrolló por lo general de una manera ágil
y fluida, siendo la etapa de aprendizaje de ExtJS e inicios de su uso el único momento
en el que hubo una ralentización notable. Esto se debió sobre todo a la inexistencia de un
tutorial decente, documentación inacabada y elementos sin documentación (experimentales
o ad hoc) que requirieron múltiples pruebas o personalización por parte del alumno. Pese a
ello podemos afirmar sin dudas que también en ese aspecto el proyecto tuvo un resultado
satisfactorio, aportando conocimientos nuevos y experiencia al alumno en cada uno de sus
apartados.
Anexo A

Diagramas adicionales

104
A.1. Diagramas Entidad-Relación 105

A.1. Diagramas Entidad-Relación

Figura A.1: diagrama E-R del modelo final de la BD


A.2. Diagramas UML 106

A.2. Diagramas UML

Figura A.2: diagrama UML del modelo final de la BD empleado en tedia2sql


A.2. Diagramas UML 107

Figura A.3: diagrama UML de todos los DAOs existentes en PhpReport (1/4)
A.2. Diagramas UML 108

Figura A.4: diagrama UML de todos los DAOs existentes en PhpReport (2/4)
A.2. Diagramas UML 109

Figura A.5: diagrama UML de todos los DAOs existentes en PhpReport (3/4)
A.2. Diagramas UML 110

Figura A.6: diagrama UML de todos los DAOs existentes en PhpReport (4/4)
A.2. Diagramas UML 111

Figura A.7: diagrama UML de todos los VO existentes en PhpReport


A.2. Diagramas UML 112

Figura A.8: diagrama UML de todas las fachadas existentes en PhpReport


Anexo B

Código

B.1. Planificación de trabajo

Código B.1: fragmento de un DAO de PostgreSQL de ejemplo, PostgreSQLModuleDAO.php


1
2 /∗∗ Module v a l u e o b j e c t c o n s t r u c t o r f o r PostgreSQL .
3 ∗
4 ∗ T h i s f u n c t i o n c r e a t e s a new { @ l i n k ModuleVO} w i t h d a t a r e t r i e v e d from d a t a b a s e .
5 ∗
6 ∗ @param a r r a y $row an a r r a y w i t h t h e Module v a l u e s from a row .
7 ∗ @ r e t u r n ModuleVO a { @ l i n k ModuleVO} w i t h i t s p r o p e r t i e s s e t t o t h e v a l u e s from <v a r>$row</v a r >.
8 ∗ @see ModuleVO
9 ∗/
10 p r o t e c t e d f u n c t i o n s e t V a l u e s ( $row )
11 {
12
13 $moduleVO = new ModuleVO ( ) ;
14
15 $moduleVO−>s e t I d ( $row [ i d ] ) ;
16 $moduleVO−>setName ( $row [ name ] ) ;
17 $moduleVO−>s e t I n i t ( d a t e c r e a t e ( $row [ i n i t ] ) ) ;
18 $moduleVO−>s e t E n d ( d a t e c r e a t e ( $row [ e n d ] ) ) ;
19 $moduleVO−>setSummary ( $row [ summary ] ) ;
20 $moduleVO−>s e t P r o j e c t I d ( $row [ p r o j e c t i d ] ) ;
21
22 r e t u r n $moduleVO ;
23
24 }
25
26 /∗∗ Module r e t r i e v e r by i d f o r PostgreSQL .
27 ∗
28 ∗ T h i s f u n c t i o n r e t r i e v e s t h e row from Module t a b l e w i t h t h e i d <v a r>$ m o d u l e I d </v a r> and c r e a t e s a {
@ l i n k ModuleVO} w i t h i t s d a t a .
29 ∗
30 ∗ @param i n t $ m o d u l e I d t h e i d o f t h e row we want t o r e t r i e v e .
31 ∗ @ r e t u r n ModuleVO a v a l u e o b j e c t { @ l i n k ModuleVO} w i t h i t s p r o p e r t i e s s e t t o t h e v a l u e s from t h e row
.
32 ∗ @t hr ow s { @ l i n k S Q L Q u e r y E r r o r E x c e p t i o n }
33 ∗/
34 p u b l i c f u n c t i o n getById ( $moduleId ) {
35
36 if ( ! i s n u m e r i c ( $moduleId ) )
37 t h r o w new S Q L I n c o r r e c t T y p e E x c e p t i o n ( $ m o d u l e I d ) ;
38
39 $ s q l = ”SELECT ∗ FROM module WHERE i d=” . $ m o d u l e I d ;
40 $ r e s u l t = $ t h i s −>e x e c u t e ( $ s q l ) ;
41
42 return $result [ 0 ] ;
43
44 }
45
46 /∗∗ Module u p d a t e r f o r PostgreSQL .
47 ∗
48 ∗ T h i s f u n c t i o n u p d a t e s t h e d a t a o f a Module by i t s { @ l i n k ModuleVO } .
49 ∗
50 ∗ @param ModuleVO $moduleVO t h e { @ l i n k ModuleVO} w i t h t h e d a t a we want t o u p d a t e on d a t a b a s e .
51 ∗ @ r e t u r n i n t t h e number o f r o w s t h a t h a v e b e e n a f f e c t e d ( i t s h o u l d be 1 ) .
52 ∗ @t hr ow s { @ l i n k S Q L Q u e r y E r r o r E x c e p t i o n } , { @ l i n k S Q L U n i q u e V i o l a t i o n E x c e p t i o n }
53 ∗/
54 p u b l i c f u n c t i o n u p d a t e ( ModuleVO $moduleVO ) {
55
56 $affectedRows = 0;

113
B.1. Planificación de trabajo 114

57
58 i f ( $moduleVO−>g e t I d ( ) != ” ” ) {
59 $currModuleVO = $ t h i s −>g e t B y I d ( $moduleVO−>g e t I d ( ) ) ;
60 }
61
62 // I f t h e q u e r y r e t u r n e d a row t h e n u p d a t e
63 i f ( s i z e o f ( $currModuleVO ) > 0 ) {
64
65 $ s q l = ”UPDATE module SET name=” . D B P o s t g r e s : : c h e c k S t r i n g N u l l ( $moduleVO−>getName ( ) ) .
” , i n i t =” . D B P o s t g r e s : : f o r m a t D a t e ( $moduleVO−>g e t I n i t ( ) ) . ” , e n d=” .
D B P o s t g r e s : : f o r m a t D a t e ( $moduleVO−>g e t E n d ( ) ) . ” , summary=” . D B P o s t g r e s : :
c h e c k S t r i n g N u l l ( $moduleVO−>getSummary ( ) ) . ” , p r o j e c t i d=” . D B P o s t g r e s : : c h e c k N u l l
( $moduleVO−>g e t P r o j e c t I d ( ) ) . ” WHERE i d=” . $moduleVO−>g e t I d ( ) ;
66
67 $ r e s = p g q u e r y ( $ t h i s −>c o n n e c t , $ s q l ) ;
68
69 i f ( $ r e s == NULL)
70 i f ( strpos ( p g l a s t e r r o r () , ” unique module project name ”) )
71 t h r o w new S Q L U n i q u e V i o l a t i o n E x c e p t i o n ( p g l a s t e r r o r ( ) ) ;
72 e l s e t h r o w new S Q L Q u e r y E r r o r E x c e p t i o n ( p g l a s t e r r o r ( ) ) ;
73
74 $affectedRows = pg affected rows ( $res ) ;
75 }
76
77 return $affectedRows ;
78
79 }
80
81 /∗∗ Module c r e a t o r f o r PostgreSQL .
82 ∗
83 ∗ T h i s f u n c t i o n c r e a t e s a new row f o r a Module by i t s { @ l i n k ModuleVO } .
84 ∗ The i n t e r n a l i d o f <v a r>$moduleVO</v a r> w i l l be s e t a f t e r i t s c r e a t i o n .
85 ∗
86 ∗ @param ModuleVO $moduleVO t h e { @ l i n k ModuleVO} w i t h t h e d a t a we want t o i n s e r t on d a t a b a s e .
87 ∗ @ r e t u r n i n t t h e number o f r o w s t h a t h a v e b e e n a f f e c t e d ( i t s h o u l d be 1 ) .
88 ∗ @t hr ow s { @ l i n k S Q L Q u e r y E r r o r E x c e p t i o n } , { @ l i n k S Q L U n i q u e V i o l a t i o n E x c e p t i o n }
89 ∗/
90 p u b l i c f u n c t i o n c r e a t e ( ModuleVO $moduleVO ) {
91
92 $affectedRows = 0;
93
94 $ s q l = ”INSERT INTO module ( name , i n i t , e nd , summary , p r o j e c t i d ) VALUES( ” . D B P o s t g r e s : :
c h e c k S t r i n g N u l l ( $moduleVO−>getName ( ) ) . ” , ” . D B P o s t g r e s : : f o r m a t D a t e ( $moduleVO−>g e t I n i t
( ) ) . ” , ” . D B P o s t g r e s : : f o r m a t D a t e ( $moduleVO−>g e t E n d ( ) ) . ” , ” . D B P o s t g r e s : :
c h e c k S t r i n g N u l l ( $moduleVO−>getSummary ( ) ) . ” , ” . D B P o s t g r e s : : c h e c k N u l l ( $moduleVO−>
getProjectId () ) . ”)” ;
95
96 $ r e s = p g q u e r y ( $ t h i s −>c o n n e c t , $ s q l ) ;
97
98 i f ( $ r e s == NULL)
99 i f ( strpos ( p g l a s t e r r o r () , ” unique module project name ”) )
100 t h r o w new S Q L U n i q u e V i o l a t i o n E x c e p t i o n ( p g l a s t e r r o r ( ) ) ;
101 e l s e t h r o w new S Q L Q u e r y E r r o r E x c e p t i o n ( p g l a s t e r r o r ( ) ) ;
102
103 $moduleVO−>s e t I d ( D B P o s t g r e s : : g e t I d ( $ t h i s −>c o n n e c t , ” m o d u l e i d s e q ” ) ) ;
104
105 $affectedRows = pg affected rows ( $res ) ;
106
107 return $affectedRows ;
108
109 }
110
111 /∗∗ Module d e l e t e r f o r PostgreSQL .
112 ∗
113 ∗ T h i s f u n c t i o n d e l e t e s t h e d a t a o f a Module by i t s { @ l i n k ModuleVO } .
114 ∗
115 ∗ @param ModuleVO $moduleVO t h e { @ l i n k ModuleVO} w i t h t h e d a t a we want t o d e l e t e from d a t a b a s e .
116 ∗ @ r e t u r n i n t t h e number o f r o w s t h a t h a v e b e e n a f f e c t e d ( i t s h o u l d be 1 ) .
117 ∗ @t hr ow s { @ l i n k S Q L Q u e r y E r r o r E x c e p t i o n }
118 ∗/
119 p u b l i c f u n c t i o n d e l e t e ( ModuleVO $moduleVO ) {
120 $affectedRows = 0;
121
122 // Check f o r a module ID .
123 i f ( $moduleVO−>g e t I d ( ) >= 0 ) {
124 $currModuleVO = $ t h i s −>g e t B y I d ( $moduleVO−>g e t I d ( ) ) ;
125 }
126
127 // O t h e r w i s e d e l e t e a module .
128 i f ( s i z e o f ( $currModuleVO ) > 0 ) {
129 $ s q l = ”DELETE FROM module WHERE i d=” . $moduleVO−>g e t I d ( ) ;
130
131 $ r e s = p g q u e r y ( $ t h i s −>c o n n e c t , $ s q l ) ;
132 i f ( $ r e s == NULL) t h r o w new S Q L Q u e r y E r r o r E x c e p t i o n ( p g l a s t e r r o r ( ) ) ;
133 $affectedRows = pg affected rows ( $res ) ;
134 }
135
B.1. Planificación de trabajo 115

136 return $affectedRows ;


137 }

Código B.1: fragmento de un DAO de PostgreSQL de ejemplo, PostgreSQLModuleDAO.php


B.2. Extracción de datos avanzada 116

B.2. Extracción de datos avanzada

Código B.2: fragmento de la acción para obtener las horas extra, ExtraHoursReportAction.php
1
2 /∗∗ T r a n s l a t e t o d a y s from e p o c h .
3 ∗
4 ∗ Compute t h e d a y s p a s s e d s i n c e a r e f e r e n c e d a t e c a l l e d ” e p o c h ” (”1970 −01 −05”).< b r/>NOTE : F o r
c o n v e n i e n c e r e a s o n s , t h e e p o c h ISN ’T THE SAME a s t h e s t a n d a r d u n i x epoch ,
5 ∗ b e c a u s e i t ’ s Monday and can be u s e d t o compute t h e week day d o i n g modulus .
6 ∗
7 ∗ @param DateTime $ d a t e t h e d a t e t h a t we want t o t r a n s l a t e t o d a y s from e p o c h .
8 ∗ @ r e t u r n i n t t h e number o f d a y s s i n c e 1970−01−05.
9 ∗/
10 p r i v a t e f u n c t i o n daysFromEpoch ( DateTime $ d a t e ) {
11 $aux = d a t e c r e a t e ( $ d a t e−>f o r m a t ( ”Y−m−d” ) ) ; // <−−−− T h i s c o d e a c t s a s a w o r k a r o u n d w i t h a PHP bug
12
13 // 1970−01−05 i s a b e t t e r e p o c h day , b e c a u s e i t ’ s Monday and can be
14 // u s e d t o compute t h e week day d o i n g modulus
15
16 $aux2 = $aux−>d i f f ( d a t e c r e a t e ( ”1970−01−05” ) ) ;
17 $ r e s u l t = $aux2−>d a y s ;
18 return $result ;
19 }
20
21
22 /∗∗ Compute t h e number o f w o r k i n g d a y s .
23 ∗
24 ∗ Compute t h e number o f w o r k i n g d a y s b e t w e e n two g i v e n d a t e s ( b o t h i n c l u d e d ) .
25 ∗
26 ∗ @param DateTime $ i n i t t h e i n i t d a t e o f t h e i n t e r v a l .
27 ∗ @param DateTime $end t h e e n d i n g d a t e o f t h e i n t e r v a l .
28 ∗ @ r e t u r n i n t t h e number o f w o r k i n g d a y s b e t w e e n t h e two d a t e s .
29 ∗/
30 p r i v a t e f u n c t i o n numWorkDays ( DateTime $ i n i t , DateTime $end ) {
31 // T a k i n g on a c c o u n t t h e t h i n g s s a i d i n f u n c t i o n num w e e ke nd days ,
32 // t h i s i s a f u n c t i o n t h a t w o r k s i n a s i m i l a r way t o g e t t h e number
33 // o f ∗work∗ d a y s ( t h a t means e x c l u d i n g w e e k e n d s ) b e t w e e n two d a t e s .
34
35 // NOTE : −1 b e c a u s e we a l s o i n c l u d e t h e s t a r t d a t e
36 // ( i n i t <=x<=end , INSTEAD OF i n i t <x<=end )
37 $ d a y s e p o c h t o i n i t=$ t h i s −>daysFromEpoch ( $ i n i t ) −1;
38 $ d a y s e p o c h t o e n d=$ t h i s −>daysFromEpoch ( $end ) ;
39 $ w e e k e n d d a y s e p o c h t o i n i t=f l o o r ( $ d a y s e p o c h t o i n i t / 7 ) ∗ 2 ;
40 i f ( $ d a y s e p o c h t o i n i t %7==5) $ w e e k e n d d a y s e p o c h t o i n i t +=1;
41 e l s e i f ( $ d a y s e p o c h t o i n i t %7==6) $ w e e k e n d d a y s e p o c h t o i n i t +=2;
42
43 $ w e e k e n d d a y s e p o c h t o e n d=f l o o r ( $ d a y s e p o c h t o e n d / 7 ) ∗ 2 ;
44 i f ( $ d a y s e p o c h t o e n d %7==5) $ w e e k e n d d a y s e p o c h t o e n d +=1;
45 e l s e i f ( $ d a y s e p o c h t o e n d %7==6) $ w e e k e n d d a y s e p o c h t o e n d +=2;
46
47 $result = $days epoch to end − $days epoch to init −
48 ( $weekend days epoch to end − $weekend days epoch to init ) ;
49
50
51 return $result ;
52 }
53
54
55 /∗∗ Compute t h e number o f e x t r a h o u r s worked
56 ∗
57 ∗ Compute t h e number o f e x t r a h o u r s u s e r s h a v e worked b e t w e e n two d a t e s ( b o t h i n c l u d e d ) .
58 ∗ We can p a s s an o p t i o n a l p a r a m e t e r , <v a r>$ u s e r </v a r >, i f we want t o compute o n l y a U s e r d a t a .
59 ∗ <b r/><b r/> I t r e t u r n s an a s s o c i a t i v e a r r a y w i t h t h e f o l l o w i n g d a t a r e l a t e d t o e a c h U s e r ’ s l o g i n :
60 ∗ <u l>
61 ∗ <l i >’ t o t a l h o u r s ’ : number o f t o t a l h o u r s a U s e r h a s worked i n t h e s p e c i f i e d i n t e r v a l .</ l i >
62 ∗ <l i >’ w o r k a b l e h o u r s ’ : number o f h o u r s a U s e r must work i n t h e s p e c i f i e d i n t e r v a l a c c o r d i n g t o h i s /
h e r j o u r n e y .</ l i >
63 ∗ <l i >’ e x t r a h o u r s ’ : number o f e x t r a h o u r s a U s e r h a s worked , a c c o r d i n g t o t h e p r e v i o u s d a t a .</ l i ></
u l>
64 ∗
65 ∗ @param DateTime $ i n i t t h e i n i t d a t e o f t h e i n t e r v a l .
66 ∗ @param DateTime $end t h e e n d i n g d a t e o f t h e i n t e r v a l .
67 ∗ @param UserVO $ u s e r t h e U s e r whose e x t r a h o u r s we want t o compute .
68 ∗/
69 p r i v a t e f u n c t i o n n e t E x t r a H o u r s ( DateTime $ i n i t , DateTime $end , UserVO $ u s e r = NULL) {
70
71 $ t a s k D a o = DAOFactory : : getTaskDAO ( ) ;
72 $commonDao = DAOFactory : : getCommonEventDAO ( ) ;
73 $ j o u r n e y H i s t o r y D a o = DAOFactory : : g e t J o u r n e y H i s t o r y D A O ( ) ;
74 $ c i t y H i s t o r y D a o = DAOFactory : : g e t C i t y H i s t o r y D A O ( ) ;
75
76 i f ( i s n u l l ( $user ) )
77 {
B.2. Extracción de datos avanzada 117

78 $groupDAO = DAOFactory : : getUserGroupDAO ( ) ;


79 $ u s e r s = $groupDAO−>g e t U s e r s B y U s e r G r o u p N a m e ( C o n f i g u r a t i o n P a r a m e t e r s M a n a g e r : :
g e t P a r a m e t e r ( ”ALL USERS GROUP” ) ) ;
80 }
81 else
82 {
83 $users = array ( $user ) ;
84 }
85
86 $us e r Wor k = a r r a y ( ) ;
87
88 f o r e a c h ( $ u s e r s a s $userVO )
89 {
90 i f ( ! i s n u l l ( $userVO−>g e t I d ( ) ) )
91 {
92 $hour s Wor ke d = $taskDao−>g e t T a s k R e p o r t ( $userVO , $ i n i t , $end , ”USER” ) ;
93
94 $ j o u r n e y H i s t o r y = $ j o u r n e y H i s t o r y D a o −>g e t B y I n t e r v a l s ( $ i n i t , $end , $userVO−>
getId () ) ;
95
96 $ c i t y H i s t o r y = $ c i t y H i s t o r y D a o −>g e t B y I n t e r v a l s ( $ i n i t , $end , $userVO−>g e t I d ( ) ) ;
97
98 i f ( i s n u l l ( $hour s Wor ke d [ 0 ] [ a d d h o u r s ] ) )
99 $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” t o t a l h o u r s ” ] = 0 ;
100 else
101 $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” t o t a l h o u r s ” ] = $hour s Wor ke d [ 0 ] [
add hours ] ;
102 $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” w o r k a b l e h o u r s ” ] = 0 ;
103
104 $ h i s t o r i e s = array () ;
105
106 $i = 0;
107
108 foreac h ( ( a r r a y ) $ j o u r n e y H i s t o r y as $journeyRow )
109 foreach (( a r r a y ) $ c i t y H i s t o r y as $cityRow )
110 {
111
112 $ n e w P e r i o d = FALSE ;
113
114 // We c h e c k i f t h e h i s t o r y e n t r i e s h a v e a commmon p e r i o d ( we
f i r s t c h e c k i f t h e i r end d a t e s a r e n u l l , s o we know what
to check next )
115
116 if ( ! i s n u l l ( $j our ne yR ow−>g e t E n d D a t e ( ) ) )
117 i f ( ! i s n u l l ( $ c i t y R o w−>g e t E n d D a t e ( ) ) )
118 {
119 i f ( ! ( ( $j our ne yR ow−>g e t I n i t D a t e ( ) < $ c i t y R o w−>
g e t I n i t D a t e ( ) ) && ( $j our ne yR ow−>
g e t E n d D a t e ( ) < $ c i t y R o w−>g e t I n i t D a t e ( ) ) )
&& ! ( ( $j our ne yR ow−>g e t I n i t D a t e ( ) >
$ c i t y R o w−>g e t E n d D a t e ( ) ) && ( $j our ne yR ow−>
g e t E n d D a t e ( ) > $ c i t y R o w−>g e t E n d D a t e ( ) ) ) )
120 $ n e w P e r i o d = TRUE ;
121 } else
122 {
123 i f ( ! ( ( $j our ne yR ow−>g e t I n i t D a t e ( ) < $ c i t y R o w−>
g e t I n i t D a t e ( ) ) && ( $j our ne yR ow−>
g e t E n d D a t e ( ) < $ c i t y R o w−>g e t I n i t D a t e ( ) ) ) )
124 $ n e w P e r i o d = TRUE ;
125 }
126
127 else
128 {
129 if ( ! i s n u l l ( $ c i t y R o w−>g e t E n d D a t e ( ) ) )
130 {
131 if ( ! ( ( $ c i t y R o w−>g e t I n i t D a t e ( ) < $j our ne yR ow−>
g e t I n i t D a t e ( ) ) && ( $ c i t y R o w−>g e t E n d D a t e ( )
< $j our ne yR ow−>g e t I n i t D a t e ( ) ) ) )
132 $ n e w P e r i o d = TRUE ;
133 }
134 e l s e $ n e w P e r i o d = TRUE ;
135 }
136
137 i f ( $newPeriod )
138 {
139 $ h i s t o r i e s [ $ i ] [ ” i n i t ” ] = $j our ne yR ow−>g e t I n i t D a t e ( ) ;
140 $ h i s t o r i e s [ $ i ] [ ” end ” ] = $j our ne yR ow−>g e t E n d D a t e ( ) ;
141 $ h i s t o r i e s [ $ i ] [ ” j o u r n e y ” ] = $j our ne yR ow−>g e t J o u r n e y ( ) ;
142
143 if ( ( $ h i s t o r i e s [ $ i ] [ ” i n i t ” ] < $ c i t y R o w−>g e t I n i t D a t e ( ) )
&& ( i s n u l l ( $ h i s t o r i e s [ $ i ] [ ” end ” ] ) | | (
$ h i s t o r i e s [ $ i ] [ ” end ” ] > $ c i t y R o w−>g e t I n i t D a t e ( ) ) )
)
144 $ h i s t o r i e s [ $ i ] [ ” i n i t ” ] = $ c i t y R o w−>g e t I n i t D a t e
() ;
145
B.2. Extracción de datos avanzada 118

146 i f ( i s n u l l ( $ h i s t o r i e s [ $ i ] [ ” end ” ] ) | | ( ( $ h i s t o r i e s [ $ i
] [ ” end ” ] > $ c i t y R o w−>g e t E n d D a t e ( ) ) ) && (
$ h i s t o r i e s [ $ i ] [ ” i n i t ” ] < $ c i t y R o w−>g e t E n d D a t e ( ) ) )
147 $ h i s t o r i e s [ $ i ] [ ” end ” ] = $ c i t y R o w−>g e t E n d D a t e ( )
;
148
149 // I f b o t h d a t e s a r e NULL , t h e n end d a t e i s nowadays
150
151 i f ( i s n u l l ( $ h i s t o r i e s [ $ i ] [ ” end ” ] ) )
152 $ h i s t o r i e s [ $ i ] [ ” end ” ] = new DateTime ( ) ;
153
154 $ h i s t o r i e s [ $ i ] [ ” c i t y ” ] = $ c i t y R o w−>g e t C i t y I d ( ) ;
155
156 $ i ++;
157 }
158 }
159
160 $hours = 0;
161
162 f o r e a c h ( ( a r r a y ) $ h i s t o r i e s a s $row )
163 {
164
165 i f ( $row [ ” i n i t ” ] < $ i n i t )
166 $row [ ” i n i t ” ] = $ i n i t ;
167
168 i f ( $row [ ” end ” ] > $end )
169 $row [ ” end ” ] = $end ;
170
171 $work = $ t h i s −>numWorkDays ( $row [ ” i n i t ” ] , $row [ ” end ” ] ) ;
172 $ h o l i d a y s = c o u n t ( $commonDao−>g e t B y C i t y I d D a t e s ( $row [ ” c i t y ” ] , $row [ ”
i n i t ” ] , $row [ ” end ” ] ) ) ;
173 $ w o r k H o u r s = ( $work − $ h o l i d a y s ) ∗ $row [ ” j o u r n e y ” ] ;
174 $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” w o r k a b l e h o u r s ” ] += $ w o r k H o u r s ;
175
176 }
177
178 $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” e x t r a h o u r s ” ] = $us e r Wor k [ $userVO−>g e t L o g i n ( )
] [ ” t o t a l h o u r s ” ] − $us e r Wor k [ $userVO−>g e t L o g i n ( ) ] [ ” w o r k a b l e h o u r s ” ] ;
179 }
180
181 }
182
183 r e t u r n $us e r Wor k ;
184 }

Código B.2: fragmento de la acción para obtener las horas extra, ExtraHoursReportAction.php
B.2. Extracción de datos avanzada 119

Código B.3: fragmento de la acción para obtener las horas de vacaciones pendientes,
GetPendingHolidayHoursAction.php
1
2 // We compute t h e h o l i d a y h o u r s f o r e a c h U s e r
3 f o r e a c h ( ( a r r a y ) $ u s e r s a s $userVO )
4 {
5
6 // We o n l y compute i t f o r w o r k e r s , s o t h e y must be i n a g r o u p
7 i f ( ! i s n u l l ( $userVO−>g e t G r o u p s ( ) ) )
8 {
9
10 // We g e t h i s / h e r j o u r n e y s i n t h e d a t e i n t e r v a l
11 $ j o u r n e y H i s t o r y = $ j o u r n e y H i s t o r y D a o −>g e t B y I n t e r v a l s ( $ t h i s −>i n i t , $ t h i s −>end , $userVO
−>g e t I d ( ) ) ;
12
13 // He/ s h e s t a r t s w i t h no worked h o u r s
14 $workHours = 0 ;
15
16 foreac h ( ( a r r a y ) $ j o u r n e y H i s t o r y as $journeyRow )
17 {
18
19 // F i r s t o f a l l , we c l i p t h e i n t e r v a l w i t h t h e j o u r n e y
20 $ i n i t = $j our ne yR ow−>g e t I n i t D a t e ( ) ;
21 $end = $j our ne yR ow−>g e t E n d D a t e ( ) ;
22
23 i f ( $ i n i t <$ t h i s −>i n i t )
24 $ i n i t = $ t h i s −>i n i t ;
25
26 i f ( $end>$ t h i s −>end )
27 $end = $ t h i s −>end ;
28
29 // We g e t t h e d i f f e r e n c e i n d a y s . . .
30 $ d i f f J o u r n e y = $ i n i t −>d i f f ( $end ) ;
31 // and w i t h i t and t h e j o u r n e y , t h e worked h o u r s ( p l u s one day b e c a u s e i t ’ s a
closed ending i n t e r v a l )
32 $ w o r k H o u r s += ( $ d i f f J o u r n e y −>d a y s + 1 ) ∗( $j our ne yR ow−>g e t J o u r n e y ( ) ) ;
33
34
35 // We must c h e c k f o r l e a p y e a r s on t h e i n t e r v a l
36 $ i n i t Y e a r = $ i n i t −>f o r m a t ( ”Y” ) ;
37
38 // Go from t h e i n i t y e a r t o t h e end one
39 w h i l e ( $ i n i t Y e a r <= $end−>f o r m a t ( ”Y” ) )
40 {
41
42 // We c h e c k i f t h e y e a r i s a l e a p one , and i f f e b r u a r y 29 t h i s i n t h e
i n t e r v a l . T h e r e can be some u s e l e s s c h e c k i n g s h e r e
43 // ( f e b r u a r y 29 t h can be p r i o r t o t h e i n i t o n l y i n t h e f i r s t y e a r , and
l a t e r t h a n t h e end on t h e l a s t one ) , b u t i t ’ s no
44 // much c o m p u t a t i o n anyway , and t h e c o d e i s c l e a r ( and i t ’ s a l r e a d y
hard to understand at f i r s t )
45 i f ( checkdate (02 ,29 , $ i n i t Y e a r ) )
46 i f ( ( $ i n i t < d a t e c r e a t e ( $ i n i t Y e a r . ”−02−29” ) ) && ( $end >=
d a t e c r e a t e ( $ i n i t Y e a r . ”−02−29” ) ) )
47 $ w o r k H o u r s −= $j our ne yR ow−>g e t J o u r n e y ( ) ; // I t ’
s a l e a p y e a r , s o we s u b t r a c t one j o u r n e y f o r
f e b r u a r y 29 t h
48
49 $ i n i t Y e a r ++;
50 }
51
52 }
53
54 // We g e t t h e v a c a t i o n s he / s h e h a s s p e n t i n t h e i n t e r v a l
55 $ v a c a t i o n s = $taskDao−>g e t V a c a t i o n s ( $userVO , $ t h i s −>i n i t , $ t h i s −>end ) ;
56
57 // Y e a r l y h o l i d a y h o u r s i s t h e s t a n d a r d f o r an 8−h o u r j o u r n e y o v e r a y e a r , s o t h e
result is proportional
58 $ h o l i d a y H o u r s = ( $workHours /(365∗8) )∗ C o n f i g u r a t i o n P a r a m e t e r s M a n a g e r : : getParameter ( ’
YEARLY HOLIDAY HOURS ’ ) ;
59
60 // The d i f f e r e n c e i s t h e number o f p e n d i n g h o l i d a y h o u r s
61 $ u s e r P e n d i n g H o l i d a y H o u r s [ $userVO−>g e t L o g i n ( ) ]= $ h o l i d a y H o u r s −$ v a c a t i o n s [ ” a d d h o u r s ” ] ;
62
63 }
64
65 }
66
67 return $userPendingHolidayHours ;

Código B.3: fragmento de la acción para obtener las horas de vacaciones pendientes,
GetPendingHolidayHoursAction.php
Anexo C

Glosario de acrónimos

AJAX Asynchronous JavaScript And XML

API Application Programming Interface

BD Base de Datos

BSD Berkeley Software Distribution

CDDL Common Development and Distribution License

CO Custom Object

CRUD Create Read Update Delete

CSS Cascading Style Sheets

DAO Data Access Object

DB Database

DDL Data Definition Language

DER Diagrama Entidad-Relación

DHTML Dynamic HTML

DOM Document Object Model

DSL Domain Specific Language

E-R Entidad-Relación

GPL General Public License

GNU GNU is Not Unix

HTML HyperText Markup Language

HTTP HyperText Transfer Protocol

IDE Integrated Development Environment

120
121

JSON JavaScript Object Notation

LDAP Lightweight Directory Access Protocol

MathML Mathematical Markup Language

PHP PHP Hypertext Preprocessor

POO Programación Orientada a Objetos

RIA Rich Internet Applications

SGML Standard Generalized Markup Language

SQL Structured Query Language

SSL Secure Socket Layer

SVG Scalable Vector Graphics

VCS Version Control System

VO Value Object

VOIP Voice Over IP

W3C World Wide Web Consortium

XHTML Extensible HyperText Markup Language

XML Extensible Markup Language

XP Extreme Programming
Referencias

[1] “Sitio oficial de Igalia.” http://www.igalia.com/.

[2] “Wikipedia.” http://wikipedia.org.

[3] “POO en la Wikipedia.” http://es.wikipedia.org/wiki/Programaci%C3%B3n_


orientada_a_objetos.

[4] “Programación declarativa en la Wikipedia.” http://es.wikipedia.org/wiki/


Programaci%C3%B3n_declarativa.

[5] “Programación funcional en la Wikipedia.” http://es.wikipedia.org/wiki/


Programaci%C3%B3n_funcional.

[6] “PHP en la Wikipedia.” http://es.wikipedia.org/wiki/PHP.

[7] “Sitio oficial de PHP.” http://www.php.net/.

[8] “MySQL en la Wikipedia.” http://es.wikipedia.org/wiki/MySQL.

[9] “Sitio oficial de MySQL.” http://www.mysql.com/.

[10] “Sitio oficial de PHPUnit.” http://www.phpunit.de/.

[11] “JavaScript en la Wikipedia.” http://es.wikipedia.org/wiki/JavaScript.

[12] “Sitio oficial de JavaScript.” https://developer.mozilla.org/en/JavaScript.

[13] “AJAX en la Wikipedia.” http://es.wikipedia.org/wiki/AJAX.

[14] “RIA en la Wikipedia.” http://es.wikipedia.org/wiki/Rich_Internet_


Applications.

[15] “ExtJS en la Wikipedia.” http://es.wikipedia.org/wiki/ExtJS.

[16] “Sitio oficial de ExtJS.” http://www.extjs.com.

[17] “jQuery en la Wikipedia.” http://es.wikipedia.org/wiki/Jquery.

[18] “Sitio oficial de jQuery.” http://www.jquery.com.

[19] “Prototype en la Wikipedia.” http://es.wikipedia.org/wiki/Prototype.

122
REFERENCIAS 123

[20] “Sitio oficial de Prototype.” http://www.prototypejs.org.

[21] “PostgreSQL en la Wikipedia.” http://es.wikipedia.org/wiki/Postgresql.

[22] “Sitio oficial de PostgreSQL.” http://www.postgresql.org/.

[23] “Apache en la Wikipedia.” http://es.wikipedia.org/wiki/Servidor_HTTP_


Apache.

[24] “Sitio oficial de Apache.” http://httpd.apache.org/.

[25] “XML en la Wikipedia.” http://es.wikipedia.org/wiki/XML.

[26] “Sitio oficial de XML.” http://www.w3.org/XML/.

[27] “JSON en la Wikipedia.” http://es.wikipedia.org/wiki/JSON.

[28] “Sitio oficial de JSON.” http://www.json.org/.

[29] “HTML en la Wikipedia.” http://es.wikipedia.org/wiki/Html.

[30] “Especificación de HTML.” http://www.w3.org/TR/html401/.

[31] “Sitio oficial de Selenium.” http://seleniumhq.org/.

[32] “Selenium en la Wikipedia.” http://en.wikipedia.org/wiki/Selenium_


%28software%29.

[33] “UML en la Wikipedia.” http://es.wikipedia.org/wiki/Uml.

[34] “Sitio oficial de UML.” http://www.uml.org/.

[35] “Entidad-Relación en la Wikipedia.” http://es.wikipedia.org/wiki/Modelo_


entidad-relaci%C3%B3n.

[36] P. Chen et al., Entity-Relationship Modeling: Historical Events, Future Trends, and
Lessons Learned. Louisiana State University, Baton Rouge, LA 70803, USA. http://
bit.csc.lsu.edu/~chen/pdf/Chen_Pioneers.pdf.

[37] “Modelo Relacional en la Wikipedia.” http://es.wikipedia.org/wiki/Modelo_


relacional.

[38] “Sitio oficial de OpenSSH.” http://www.openssh.com/.

[39] “Sitio oficial de Emacs.” http://www.gnu.org/software/emacs/.

[40] “Sitio oficial de VIM.” http://www.vim.org/.

[41] “Sitio oficial de Git.” http://git-scm.com/.

[42] “Sitio oficial de Meld.” http://meld.sourceforge.net/.

[43] “Sitio oficial de PgAdmin.” http://www.pgadmin.org/.


REFERENCIAS 124

[44] “Sitio oficial de DIA.” http://live.gnome.org/Dia.

[45] “Sitio oficial de Tedia2sql.” http://tedia2sql.tigris.org/.

[46] “Sitio oficial de PHPDoc.” http://www.phpdoc.org/.

[47] “Sitio oficial de Trac.” http://trac.edgewall.org/.

[48] “Trac en la Wikipedia.” http://en.wikipedia.org/wiki/Trac.

[49] “Sitio oficial de TexMaker.” http://www.xm1math.net/texmaker/.

[50] “Sitio oficial de Eclipse.” http://www.eclipse.org/.

[51] “Sitio oficial de Doxygen.” http://www.doxygen.org/.

[52] K. Beck, Extreme Programming Explained Embrace Change. Addison-Wesley Pub


Co., Oct. 1999.

[53] “Programación extrema en la Wikipedia.” http://es.wikipedia.org/wiki/


Programaci%C3%B3n_extrema.

[54] “Sitio oficial de tWiki.” http://www.twiki.org/.

[55] “Sitio oficial de XPTracker.” http://twiki.org/cgi-bin/view/Plugins/


XpTrackerPlugin.

[56] “What’s In The Future For VoIP.” http://www.voip-voice-over-ip.com/


internet-phone/voip-future.htm.

[57] J. Reimer, “Total share: 30 years of personal computer market share figures.” http://
arstechnica.com/old/content/2005/12/total-share.ars.

[58] “Artı́culo de la Wikipedia sobre las aplicaciones de anotación de trabajo.” http://


en.wikipedia.org/wiki/Time_tracking_software.

[59] “Comparación en la Wikipedia de herramientas de time tracking.” http://en.


wikipedia.org/wiki/Comparison_of_time_tracking_software.

[60] “Historia y descripción de Linux en Wikipedia.” http://en.wikipedia.org/wiki/


Linux.

[61] P. Magnusson, “Internet Explosion.” http://www.sics.se/~psm/it_trends/


sld003.htm.

[62] R. Hobbes Zakon, “Hobbes´ Internet Timeline 10.” http://www.zakon.org/


robert/internet/timeline/.

[63] “Historia del SW libre en Wikipedia.” http://en.wikipedia.org/wiki/History_


of_free_and_open-source_software.
REFERENCIAS 125

[64] “Ejemplo de capacidades de exportación/importación.” http://www.


timetrackingsoftware.com/kbase/track_it_pro_ver_5/using_the_track_
it_pro_import_export_tool_to_export_time_entries.html.

[65] S. O’Sullivan, “History of time tracking jobs & staff in Australian and NZ
manufacturing.” http://www.google.com/url?sa=t&source=web&ct=res&
cd=3&ved=0CCYQFjAC&url=http%3A%2F%2Fwww.empowersoftware.co.nz
%2FPDFs%2FJoinersMagazineDec07.pdf&ei=8EX8S_yCHI-P4gbN1c2AAw&
usg=AFQjCNFEoXMFNAXyG7CtLbLNKF1Jmg9Qeg&sig2=YX9ao46F2ktoSOuxMuSaKw.

[66] “Ejemplo de modelo de roles.” http://www.activecollab.com/docs/manuals/


admin/configuration/roles-and-permissions.

[67] “Capacidades de data-mining en Dovico.” http://www.dovico.com/dovico_


timesheet/reports/for_downloadv10/dovico_timesheet_reports.htm.

[68] “Capacidades de data-mining de Replicon.” http://www.replicon.com/


timesheet/project-management-software-tools.aspx#A9.

[69] “Caracterı́sticas de Toggl.” http://www.toggl.com/public/tour.

[70] “Caracterı́sticas de yaTimer.” http://www.nbdtech.com/yaTimer/Screens.htm.

[71] “Diferencias en el renderizado en diversos navegadores web.” http://www.


computergripes.com/firefoxsites.html.

[72] “Caracterı́sticas de actiTime con almacenamiento remoto.” http://www.actitime.


com/actitime-online.html.

[73] “Artı́culo de la Wikipedia sobre las aplicaciones de monitorización.” http://en.


wikipedia.org/wiki/Employee_monitoring_software.

[74] “Caracterı́sticas de DutyWatch.” http://www.actymac.com/DutyWatch_Remote/.

[75] “Caracterı́sticas de Refog.” http://www.refog.es/employee-monitoring/


keyfeatures.html.

[76] “Caracterı́sticas de fanurio.” http://www.fanuriotimetracking.com/features.


html.

[77] “Caracterı́sticas de Qlockwork.” http://www.qlockwork.com/product-track-b.


html.

[78] “Caracterı́sticas de Time Tracker.” http://www.trackersuite.com/frame_time_


tracking.html.

[79] “Caracterı́sticas de algTime.” http://www.algtime.com/screenshots.

[80] “Caracterı́sticas de 1DayLater.” http://1daylater.com/.

[81] “Caracterı́sticas de actiTime descargable.” http://www.actitime.com/


actitime-downloadable.html.
[82] “Tabla de precios de ClickTime.” http://www.clicktime.com/products_ct_
pricing.asp.

[83] “Caracterı́sticas de DotProject.” http://www.dotproject.net/.

[84] “Caracterı́sticas de Rachota.” http://rachota.sourceforge.net.

[85] “Caracterı́sticas de MyTime.” http://community.igalia.com/twiki/bin/view/


MyTime/WebHome.

[86] “Caracterı́sticas de Project Hamster.” http://projecthamster.wordpress.com/.

[87] “Sintaxis de phpDocumentor.” http://manual.phpdoc.org/


HTMLframesConverter/default/.

[88] “Sintaxis de los diagramas para tedia2sql.” http://tedia2sql.tigris.org/


usingtedia2sql.html.

[89] “Patrón ((facade)) en la Wikipedia.” http://en.wikipedia.org/wiki/Facade_


pattern.

[90] “Documentación de la clase DateTime de PHP.” http://php.net/manual/en/


book.datetime.php.

[91] “Archivo de versiones de ExtJS.” http://www.extjs.com/learn/Ext_Version_


Archives.

[92] “Bug tracker de PhpReport (requiere autenticación).” https://sysgroup.igalia.


com/phpreport2/.

[93] “Sitio oficial de Bugzilla.” http://www.bugzilla.org/.

[94] “WebKit en la Wikipedia.” http://es.wikipedia.org/wiki/WebKit.

126

También podría gustarte