139 Commits
dev ... rorden

Author SHA1 Message Date
Roberto Orden Erena
44f61ee745 Diseño de pruebas
Ejecución de pruebas
Correcciones menores encontradas durante las pruebas
2019-12-31 12:20:15 +01:00
Marcos Garcia Nuñez
e3174faf34 Corregido error al validar NIFs duplicados.
Formateo del NIF introducido.
2019-12-30 18:47:30 +01:00
Marcos Garcia Nuñez
893431851b Corregido error en la lista de pacientes con pruebas médicas (Se
mostraban pacientes sin prueba médica).
Arreglos menores en la interfaz.
2019-12-30 17:55:35 +01:00
Marcos Garcia Nuñez
875f664586 No se utiliza el paciente seleccionado en el filtro para añadir una
nueva prueba.
2019-12-30 16:43:03 +01:00
Marcos Garcia Nuñez
4d22327267 Corregido error al refrescar lista tras añadir una nueva prueba. 2019-12-30 13:26:27 +01:00
Marcos Garcia Nuñez
eb0366c7e7 Cambiado tipo de datos de Date a LocalDate para pruebas médicas. 2019-12-30 12:59:14 +01:00
Marcos Garcia Nuñez
e07ed75132 Cambiado tipo de datos Date a LocalDate para componente visit. 2019-12-30 12:41:35 +01:00
Marcos Garcia Nuñez
e9f103123d Corregido icono de refresco. 2019-12-30 12:29:41 +01:00
Marcos Garcia Nuñez
37be658b42 Corregido Formato de fecha. 2019-12-30 12:19:04 +01:00
Marcos Garcia Nuñez
1dbd8ef883 Cambio en nombre de parámetro. 2019-12-30 12:16:05 +01:00
Marcos Garcia Nuñez
9435964e9e Quitada conversión de formato innecesaria. 2019-12-30 12:15:49 +01:00
Marcos Garcia Nuñez
2c55a78bc8 Quitado conversor de formato innecesarios 2019-12-30 12:15:03 +01:00
dalvarezgon
756c6dff84 Número de pacientes por doctor 2019-12-30 10:08:53 +01:00
dalvarezgon
501a07df31 Listado de médicos por CAP 2019-12-29 23:45:15 +01:00
Alejandro Linares Amado
5269237787 Merge branch 'master' of http://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-29 22:10:38 +01:00
Alejandro Linares Amado
a7ec876ca7 Verificación que la fecha y hora de la cita no sea anterior al momento
actual
2019-12-29 22:10:00 +01:00
Marcos Garcia Nuñez
f80ad15f01 Centrado de botones. 2019-12-29 22:05:26 +01:00
Marcos Garcia Nuñez
ba4a4e123c Mantiene el elemento seleccionado en la lista de pruebas. 2019-12-29 21:50:00 +01:00
Marcos Garcia Nuñez
d0e41c5d5f Corrección de error en la vista de paciente y médico de familia. 2019-12-29 21:43:28 +01:00
Marcos Garcia Nuñez
b6e4116d0f Mejoras en la gestión de pruebas médicas (filtros de búsqueda) 2019-12-29 21:33:57 +01:00
dalvarezgon
ea5f0a4352 Diálogo confirmación eliminación CAP coherente con resto sistema 2019-12-29 21:01:23 +01:00
Gabriel Paradiso
20e6ccd184 doc: tests basicos de cobertura de funcionalidades por componente 2019-12-29 19:44:03 +01:00
Alejandro Linares Amado
7f886a0922 Merge branch 'master' of http://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-29 19:05:36 +01:00
Alejandro Linares Amado
1b377f2f38 Retirada command buttom consultar 2019-12-29 19:04:33 +01:00
Alejandro Linares Amado
d1ac1fe6ba Cambio de mensajes en vistas y verificación de fecha de visita 2019-12-29 18:57:42 +01:00
Marcos Garcia Nuñez
b305c59054 Si no está autorizado, redirige por defecto a la página de login. 2019-12-29 18:09:59 +01:00
Roberto Orden Erena
4442100826 Merge branch 'master' into rorden
# Conflicts:
#	1.sources/MyHealth/src/ejb/common/CommonFacadeBean.java
2019-12-29 13:21:34 +01:00
Roberto Orden Erena
5fa3d1525a Subida y gestión de imágenes completa 2019-12-29 13:10:38 +01:00
Roberto Orden Erena
9cd602f8cf Creando un MT 2019-12-29 10:20:16 +01:00
dalvarezgon
8dc561f876 Gestión Centros de Atención Primaria 2019-12-29 00:48:29 +01:00
Roberto Orden Erena
47caa1fc54 Pequeña mejora 2019-12-28 23:06:32 +01:00
Roberto Orden Erena
2e0cc8bf36 Ver pruebas médicas casi funcionando al completo: falta cargar imagen real
Crear prueba medica: formulario comenzado.
2019-12-28 22:59:55 +01:00
Roberto Orden Erena
be08aaff6e Pequeñas correcciones en SQL 2019-12-28 22:59:26 +01:00
Alejandro Linares Amado
d889bdbd6c Merge branch 'master' of http://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-28 20:59:14 +01:00
Alejandro Linares Amado
627ee49afa Añadidas llamadas a EJB y retocada interfaz 2019-12-28 20:58:51 +01:00
Alejandro Linares Amado
b2258e7ba0 Añadir metodos addVisit, updateVisit y remove 2019-12-28 20:58:04 +01:00
Alejandro Linares Amado
74bef5814a Encoding de ficheros de proyecto en UTF-8 2019-12-28 20:55:48 +01:00
Marcos Garcia Nuñez
e7d995aa60 Datos de prueba adicionales para médicos de familia. 2019-12-28 18:04:17 +01:00
Marcos Garcia Nuñez
8bfad1cea5 Añadidos comentarios a varios métodos y clases.
Corregido nombre de método.
2019-12-28 16:03:58 +01:00
Marcos Garcia Nuñez
316b42f1f4 Corregida contraseña de médicos especialistas en datos de prueba. 2019-12-28 15:23:12 +01:00
Marcos Garcia Nuñez
c7b302c695 Cambiada información de usuario logeado. 2019-12-28 15:12:20 +01:00
Marcos Garcia Nuñez
2fe4176ef9 Cambios menores en vista home y managed Bean pasado a ViewScoped. 2019-12-28 15:12:00 +01:00
Roberto Orden Erena
af0a2cf98c Issue #40 corregida. 2019-12-28 13:23:00 +01:00
Marcos Garcia Nuñez
308fa17eba Componentes de fecha y hora e modo solo lectura (disabled) 2019-12-28 12:10:29 +01:00
Marcos Garcia Nuñez
1ee2c3be90 Especialidades ordenadas por nombre 2019-12-28 11:55:27 +01:00
Marcos Garcia Nuñez
9f3dc38744 Número de elementos en las listas de búsqueda reducido a 20 elementos. 2019-12-28 11:49:01 +01:00
Marcos Garcia Nuñez
1bd894fda1 Datos de prueba para especialidades adicionales. 2019-12-28 11:44:21 +01:00
Marcos Garcia Nuñez
3f944207cc Nuevo botón para editar médico de familia. 2019-12-28 10:17:53 +01:00
Marcos Garcia Nuñez
8321d770a0 Corregida variable de entorno JBOSS_HOME en el build.xml 2019-12-28 10:17:32 +01:00
Marcos Garcia Nuñez
a3a3a410c6 Correcciones sobre interfaz. 2019-12-27 19:07:12 +01:00
Marcos Garcia Nuñez
069bd78520 Modificación de logo. 2019-12-27 18:46:50 +01:00
Marcos Garcia Nuñez
6fae518032 Refresco correcto de la paginación. 2019-12-27 18:14:32 +01:00
Marcos Garcia Nuñez
ccf1137fd4 Más datos de prueba para probar la búsqueda de especialistas por
especialidad.
2019-12-27 18:14:16 +01:00
Marcos Garcia Nuñez
697a8e9cf7 Añadidos datos de prueba de especialistas. 2019-12-27 17:47:39 +01:00
Marcos Garcia Nuñez
974b524006 CAmbiado tipo de datos para manejar Horas a LocalTime. 2019-12-27 16:56:53 +01:00
Marcos Garcia Nuñez
2b89caf1ba Auto reorganización de imports. Eliminación de warnings. 2019-12-27 15:32:57 +01:00
Marcos Garcia Nuñez
bf05547827 Mejoras en interfaz. Quitado evento innecesario. 2019-12-27 15:00:30 +01:00
Marcos Garcia Nuñez
ac3d81fe07 Mejora en visualización de especialistas por especialidad (Vista
páginada de datos).
2019-12-27 13:38:28 +01:00
Marcos Garcia Nuñez
553cc1550e Corregido título de columna. 2019-12-27 13:37:12 +01:00
Marcos Garcia Nuñez
b7697b7bd5 Mejoras en la actualización de paneles de interfaz. 2019-12-27 12:46:12 +01:00
Marcos Garcia Nuñez
01b0615d68 Corregida dirección de email para datos de prueba. 2019-12-27 12:04:44 +01:00
Marcos Garcia Nuñez
43b2793494 Corregido error. Añadidos permisos sobre las secuencias. 2019-12-27 11:58:56 +01:00
Marcos Garcia Nuñez
3d5be6849c Renombrado método para actualizar especialidades.
Dialogo de confirmación al eliminar especialidades.
Limpieza de formulario en interfaz tras realizar la operación CRUD.
2019-12-27 02:44:24 +01:00
Marcos Garcia Nuñez
ec3b1dc1cd Filtro por paciente para la consulta y modificación de visitas por parte
de un administrador.
2019-12-27 01:41:17 +01:00
Marcos Garcia Nuñez
1d0118bcc8 Metodos para busqueda y filtrado de pacientes de forma paginada. 2019-12-27 01:40:43 +01:00
Marcos Garcia Nuñez
e8df59352f Interfaz para filtro de fechas y botón adicional. 2019-12-27 00:46:24 +01:00
Marcos Garcia Nuñez
bd243631f5 Corregido icono 2019-12-27 00:45:52 +01:00
Marcos Garcia Nuñez
7f36ca323c Navegación implementada entre las páginas de listado, visualizacización
y edición de visitas.
2019-12-27 00:13:13 +01:00
Marcos Garcia Nuñez
c3da3bdc95 Vista para editar visitas. 2019-12-26 22:39:12 +01:00
Marcos Garcia Nuñez
a851f139f7 Actualización de las páginas securizadas en el filtro. 2019-12-26 22:39:03 +01:00
Marcos Garcia Nuñez
c27a28f3a5 Estilo para OrderedList ocupe el 100% del control contenedor. 2019-12-26 22:38:33 +01:00
Marcos Garcia Nuñez
85f2cd100c Titulo de listado en la interfaz variable según el tipo de usuario. 2019-12-26 22:38:15 +01:00
Marcos Garcia Nuñez
0e861e01c6 Al añadir una pregunta no se limpiaba el formulario. 2019-12-26 22:37:45 +01:00
Marcos Garcia Nuñez
c8b16d7295 Merge branch 'rorden' into 'master'
Merge request desde Rorden a master

See merge request pds19-grupo2/myhealth!3
2019-12-26 21:52:38 +01:00
Roberto Orden Erena
0a9b2180cb Incluyo en pm2 el lanzamiento de WildFly 2019-12-26 21:23:25 +01:00
Roberto Orden Erena
6fd9e7ca6c Integradas sugerencias de la vista recibidas de Marcos, se ha tenido que
integrar con el uso de las firmas de EJB de MagicDrw, además de eliminar
el uso de propiedades sueltas en pro del objeto seleccionado, y también
se ha hecho algún cambio extra para que la botonera de la interfaz quede
más integrada.
2019-12-26 21:10:40 +01:00
Roberto Orden Erena
85f6cf9644 Revisión de código y limpieza 2019-12-26 19:13:17 +01:00
Roberto Orden Erena
87da9ccbf1 Búsqueda de especialista por especialidad 2019-12-26 18:43:16 +01:00
Roberto Orden Erena
c7de5401ad Usando las firmas del MagicDraw 2019-12-26 17:10:10 +01:00
Roberto Orden Erena
2726d2564a Cambiar nombre a TestType por MedicalTestType para ser más explicito
y refactorización de todos sus usos.
2019-12-26 12:26:02 +01:00
Roberto Orden Erena
066ddeba51 Merge branch 'master' into rorden
# Conflicts:
#	2.database/01.CreateTables.sql
#	2.database/02.Datos_prueba.sql
2019-12-26 12:25:32 +01:00
Roberto Orden Erena
b2f5cf88e4 Preguntas y respuestas funcionando al 100% 2019-12-26 12:14:12 +01:00
Gabriel Paradiso
e6aef82ba1 doc: introduccion, planificacion de pruebas y diseño de pruebas 2019-12-25 22:18:10 +01:00
dalvarezgon
6c8fb202ce Control de especialidades duplicadas 2019-12-25 21:40:31 +01:00
Roberto Orden Erena
a35d7fe7fe Preguntas y respuestas funcionando para médicos 2019-12-24 18:36:41 +01:00
Marcos Garcia Nuñez
a5eb912504 Corección doble control para mostrar mensajes en la página home. 2019-12-24 18:10:35 +01:00
Marcos Garcia Nuñez
3aa63a8cd1 autoformato de código. 2019-12-24 17:55:29 +01:00
Marcos Garcia Nuñez
0e309052ee Nuevos metodos EJB para componente de visitas. 2019-12-24 17:53:59 +01:00
Marcos Garcia Nuñez
3bd6399340 Esqueleto de vista para visualizar una visita. 2019-12-24 17:52:52 +01:00
Marcos Garcia Nuñez
ed54eb8905 Corección de interfaz para vista de la agenda del médico. 2019-12-24 17:52:35 +01:00
Marcos Garcia Nuñez
017d685538 Muestra mensaje de error si un administrador intenta actualizar su
perfil.
2019-12-24 17:52:05 +01:00
Marcos Garcia Nuñez
244bb76eec Esqueleto de nueva vista para visualizar las visitas programadas de un
paciente.
2019-12-24 17:51:43 +01:00
Marcos Garcia Nuñez
61932f6a18 Nuevas vistas para las opciones de menú de visitas. 2019-12-24 17:51:14 +01:00
Marcos Garcia Nuñez
31b794e4c9 Corrección de nombre de variable. 2019-12-24 17:50:56 +01:00
Marcos Garcia Nuñez
aa50eccbac Modificación de filtros para permitir acceso a las nuevas vistas 2019-12-24 17:50:32 +01:00
Marcos Garcia Nuñez
b37fe33906 Esqueleto de la vista para añadir una nueva visita. 2019-12-24 17:50:06 +01:00
Marcos Garcia Nuñez
96e19feb00 Cambiado tipo de datos de abstime a time. 2019-12-24 15:01:37 +01:00
Marcos Garcia Nuñez
c9cfbb3b7e Actualización de install.md con configuración del driver de postgres en JBOSS 2019-12-24 13:53:01 +01:00
Marcos Garcia Nuñez
de70fa1e8c Implementación de login automático para agilizar el desarollo.
Es necesario modificar el código del AuthorizationFilter para establecer
el usuario y contraseña que se quiere utilizar.

Este código debe eliminarse al finalizar el desarrollo.
2019-12-23 19:44:05 +01:00
Marcos Garcia Nuñez
592a0a0f97 Esqueleto para visualización de visitas. 2019-12-23 18:17:02 +01:00
Marcos Garcia Nuñez
06e42a6189 Merge branch 'master' of https://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-23 18:12:22 +01:00
Marcos Garcia Nuñez
3fe7a211ce Corrección en ruta Windows (\), cambiada a linux (/) 2019-12-23 18:10:55 +01:00
Gabriel Paradiso
d861796289 agregar datos de medical test 2019-12-23 17:56:38 +01:00
dalvarezgon
eac96114e6 Correciones página gestión especialidades 2019-12-23 17:36:54 +01:00
Marcos Garcia Nuñez
4e8cd37a3c Cambiada ruta de libreria primefaces. 2019-12-23 17:21:01 +01:00
Ubuntu
74d4162a99 Script bash para ejecutar script de BBDD de forma automática. 2019-12-23 15:55:17 +00:00
Marcos Garcia Nuñez
a329ed6a32 Campo Time de Visit a tipo time. Datos de prueba actualizados 2019-12-23 16:50:24 +01:00
Marcos Garcia Nuñez
7af0d261ab Formato fechas a standar SQL para no depender de la cultura del sistema. 2019-12-23 16:36:55 +01:00
Marcos Garcia Nuñez
524b3bb8c7 Muestra el nombre del médico logeado par el cual se está consultando la
agenda del día.
2019-12-23 16:24:10 +01:00
Marcos Garcia Nuñez
b0f5c69a47 Nueva propiedad para guardar el displayName del usuario logeado. 2019-12-23 16:23:51 +01:00
Marcos Garcia Nuñez
74ec842f54 Correción de timeZone al mostrar fechas convertidas con JSF. 2019-12-23 15:47:36 +01:00
Marcos Garcia Nuñez
7cf4a93c2c Corrección de error en paginación la refrescar datos. 2019-12-23 14:46:00 +01:00
Roberto Orden Erena
000e2a8721 Merge branch 'master' into rorden
# Conflicts:
#	2.database/02.Datos_prueba.sql
2019-12-23 12:34:11 +01:00
Marcos Garcia Nuñez
9bc06ccedd Esqueleto para consultar las visitas de un día. 2019-12-23 12:02:11 +01:00
Marcos Garcia Nuñez
94fde1e93b Nueva vista para ver visitas de un día. 2019-12-23 12:01:14 +01:00
Marcos Garcia Nuñez
4f5c5943e7 Datos de prueba para visitas. 2019-12-23 12:00:13 +01:00
Marcos Garcia Nuñez
3555348f71 Si se actualiza el nombre del perfil, se refresca la sesión y el menú
para reflejar los cambios.
2019-12-22 21:08:18 +01:00
Roberto Orden Erena
1d341cdf90 Merge branch 'master' into rorden
# Conflicts:
#	2.database/01.CreateTables.sql
#	2.database/02.Datos_prueba.sql
2019-12-22 07:32:45 +01:00
Roberto Orden Erena
5a04f0bd4f Actualización de datos y diseño BBDD 2019-12-22 07:22:56 +01:00
dalvarezgon
ed1938f44a Merge branch 'master' of https://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-21 23:12:16 +01:00
Gabriel Paradiso
917e128d7e actualizar install.md y ejecutar script de creación de datos de prueba al levantar el ambiente 2019-12-21 22:37:04 +01:00
Marcos Garcia Nuñez
a65e7fb885 Corregido action no existente. 2019-12-21 20:42:13 +01:00
Marcos Garcia Nuñez
18f2524412 Añadida cabecera y espacios de nombres. 2019-12-21 20:41:50 +01:00
Marcos Garcia Nuñez
26c3ec6a33 Incluir atributo source en el comando javac de ant. 2019-12-21 18:53:26 +01:00
Marcos Garcia Nuñez
b75199840e Eliminación de clases de interfaz del Jar EJB. 2019-12-21 18:49:40 +01:00
Marcos Garcia Nuñez
a8dd4f2674 Quitados imports innecesarios. 2019-12-21 18:47:31 +01:00
Marcos Garcia Nuñez
06388f9449 Merge branch 'master' of https://pdp-pds.eimt.uoc.edu/pds19-grupo2/myhealth.git 2019-12-21 12:56:45 +01:00
Marcos Garcia Nuñez
f62f4df779 Asociación de mensajes de validación a cada componente JSF. 2019-12-21 12:56:34 +01:00
Marcos Garcia Nuñez
14f4ac42ac Quitado código Javascript, retoques en el layout. 2019-12-21 12:56:04 +01:00
Marcos Garcia Nuñez
aee0f9deaf Corección de layout de la pagina 2019-12-21 12:55:21 +01:00
Marcos Garcia Nuñez
6a413357e5 Corrección de NIF duplicado en datos de prueba. 2019-12-21 12:54:39 +01:00
Marcos Garcia Nuñez
45c9de6546 Unificación de funciones Javscript en un fichero. 2019-12-21 12:54:23 +01:00
Marcos Garcia Nuñez
03f34d4a83 Merge branch 'docker' into 'master'
Docker env

See merge request pds19-grupo2/myhealth!2
2019-12-21 10:21:04 +01:00
Marcos Garcia Nuñez
b6d68df139 Establecer width:auto para las opciones de menú. 2019-12-20 20:14:50 +01:00
Gabriel Paradiso
d179280321 copilar codigo con ant y deployar ultima version 2019-12-20 00:35:35 +01:00
Gabriel Paradiso
904976f2cb conectarse a la db correcta 2019-12-19 23:57:02 +01:00
Gabriel Paradiso
3adff14da6 add jboss user creation scripts 2019-12-19 23:38:16 +01:00
Gabriel Paradiso
bece7c58d2 utilizar docker para ejecutar una version ya compilada, pendiente compilar y configurar usuario de jboss 2019-12-19 23:38:16 +01:00
Gabriel Paradiso
cf2140d6c7 cambiar tipo de datos para highresimage a TEXT 2019-12-19 23:36:03 +01:00
99 changed files with 5763 additions and 898 deletions

View File

@@ -22,7 +22,7 @@
<fileset dir="docroot/WEB-INF" flatten="false" inWorkspace="true" includes="**/*">
<properties/>
</fileset>
<folder name="classes\managedbean">
<folder name="classes/managedbean">
<fileset dir="bin/managedbean" flatten="false" inWorkspace="true" includes="**">
<properties/>
</fileset>

View File

@@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@@ -1,13 +1,13 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -49,8 +49,17 @@
<target name="compileEjb" depends="init">
<copy file="${sourcesrc}/META-INF/persistence.xml" todir="${buildjar}/META-INF" />
<copy file="${sourcesrc}/log4j.properties" todir="${buildjar}" />
<javac encoding="${java.encoding}" srcdir="${sourcesrc}" destdir="${buildjar}" includes="ejb/**/*.java, jpa/**/*.java, TO/**/*.java, common/**/*.java" classpathref="jboss.classpath"
includeantruntime="true" />
<javac encoding="${java.encoding}" srcdir="${sourcesrc}" destdir="${buildjar}" includeantruntime="true" source="1.8" target="1.8">
<classpath>
<path refid="jboss.classpath" />
</classpath>
<include name="ejb/**/*.java" />
<include name="jpa/**/*.java" />
<include name="TO/**/*.java" />
<include name="common/**/*.java" />
<exclude name="managedbean/**/*.java" />
</javac>
<delete verbose="true" dir="${buildjar}/managedbean" />
</target>
<!-- Update the EJB jar file and create if not exist -->
@@ -63,11 +72,16 @@
<copy todir="${buildwar}">
<fileset dir="${docroot}" />
</copy>
<javac encoding="${java.encoding}" srcdir="${sourcesrc}" destdir="${buildwar}/WEB-INF/classes" includes="managedbean/**/*.java" includeantruntime="true">
<javac encoding="${java.encoding}" srcdir="${sourcesrc}" destdir="${buildwar}/WEB-INF/classes" includeantruntime="true" source="1.8" target="1.8">
<classpath>
<path refid="jboss.classpath" />
<path refid="lib.dir" />
</classpath>
<include name="managedbean/**/*.java" />
<exclude name="ejb/**/*.java" />
<exclude name="jpa/**/*.java" />
<exclude name="TO/**/*.java" />
<exclude name="common/**/*.java" />
</javac>
<delete verbose="true" dir="${buildwar}/WEB-INF/classes/ejb" />
<delete verbose="true" dir="${buildwar}/WEB-INF/classes/jpa" />

View File

@@ -18,6 +18,10 @@
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>

View File

@@ -9,40 +9,29 @@
<title>MyHealth Online Services</title>
<h:outputStylesheet name="primeicons/primeicons.css" library="primefaces" />
<h:outputStylesheet library="css" name="estilos.css" />
<h:outputScript library="js" name="common.js" />
</h:head>
<h:outputScript>
function handleLoginRequest(xhr, status, args) {
if(args.validationFailed || !args.loggedIn) {
PF('dlgLogin').jq.effect("shake", {times:5}, 100);
PF('btnLogin').enable();
}
else {
PF('btnLogin').enable();
PF('dlgLogin').hide();
}
}
function startLogin() {
PF('btnLogin').disable();
}
// Si hay un error AJAX, lo más probable es que la sesión expirase, vamos a la página de error
function onAjaxError() {
alert('Ajax error');
window.location.href = "#{request.contextPath}/error.xhtml?type=expired";
}
</h:outputScript>
<h:body>
<p:growl id="messages" globalOnly="true" sticky="false" showDetail="true" life="15000" />
<div id="layout">
<div id="top" class="top">
<h:graphicImage library="images" name="logo-small.png" />
<h:graphicImage library="images" name="logo-small.png" height="116" alt="MyHealth by Grupo 2"/>
</div>
<div id="menuDiv" style="margin-bottom: 10px;">
<p:ajaxStatus style="width:32px; height:32px; position:fixed; right:32px; bottom:32px" onerror="onAjaxError()">
<p:ajaxStatus style="width:32px; height:32px; position:fixed; right:48px; bottom:48px" onerror="onAjaxError()">
<f:facet name="start">
<i id="loginSpin" class="pi pi-spin pi-spinner" style="font-size: 3em"></i>
<i id="loginSpin" class="pi pi-spin pi-spinner" style="font-size: 3em" />
</f:facet>
<f:facet name="error">Error!</f:facet>
<f:facet name="error">
<i class="pi pi-exclamation-triangle" style="font-size: 3em" />
</f:facet>
</p:ajaxStatus>
<h:form id="frmLogin">
@@ -71,7 +60,7 @@
<p:menubar model="#{menuView.model}">
<f:facet name="options">
<ui:fragment rendered="#{home.logedIn}">
<h:outputText value="logeado como #{home.userName} (#{home.userType}) " />
<h:outputText value="Bienvenido, #{home.userDisplayName} (#{home.userType}) " />
<p:commandButton value="Logout" icon="pi pi-sign-out" action="#{loginView.logout}" />
</ui:fragment>
<ui:fragment rendered="#{not home.logedIn}">

View File

@@ -3,59 +3,28 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<f:metadata>
<f:viewParam name="refresh" value="#{home.refresh}" />
</f:metadata>
<ui:composition template="./header.xhtml">
<ui:define name="content">
<h:form>
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel header="Pagina principal">
<div class="ui-g ui-fluid">
<div class="ui-g-12 ui-md-12">
Logeado como: <h:outputLabel value="#{home.userDisplayName}" style="font-weight: bold;" />
</div>
<div class="ui-g-2 ui-md-2">
<p:outputLabel for="selectorTema" value="Cambio de tema" />
</div>
<div class="ui-g-6 ui-md-6">
<div class="ui-g-3 ui-md-3">
<p:themeSwitcher id="selectorTema" style="width:300px" value="#{sessionPreferences.currentTheme}">
<f:selectItem itemLabel="Seleccione un tema" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{home.themes}" var="theme" itemLabel="#{theme.displayName}" itemValue="#{theme.name}" />
<p:ajax listener="#{sessionPreferences.updateCurrentTheme}" />
</p:themeSwitcher>
</div>
<div class="ui-g-4 ui-md-1" />
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-4 ui-md-4 ">
<p:commandButton value="Usar tema en este sesión" update="mesgs" action="#{sessionPreferences.updateCurrentTheme}" icon="pi pi-save" />
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2">
<div class="ui-inputgroup">
<p:calendar pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" />
<p:commandButton value="Fecha" />
</div>
</div>
<div class="ui-g-10 ui-md-10" />
<div class="ui-g-2 ui-md-2">
<h:outputLabel value="Fecha" />
<p:calendar pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" />
</div>
<div class="ui-g-10 ui-md-10" />
<div class="ui-g-12">
<h:outputLabel value="Rich Text Editor" />
</div>
<div class="ui-g-12 ui-md-12">
<p:editor />
</div>
<div class="ui-g-12 ui-md-12">
<h:outputLabel value="Logeado como:" />
<p:inputText readonly="true" value="#{home.userName}" />
<p:commandButton value="Usar tema" update="messages" action="#{sessionPreferences.updateCurrentTheme}" icon="pi pi-save" />
</div>
<div class="ui-g-5 ui-md-5" />
</div>
</p:panel>
</h:form>

View File

@@ -3,23 +3,6 @@
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<h:head>
<title>login</title>
</h:head>
<h:outputScript>
<script type="text/javascript">
function handleLoginRequest(xhr, status, args) {
if(args.validationFailed || !args.loggedIn) {
PF('dlg').jq.effect("shake", {times:5}, 100);
}
else {
PF('dlg').hide();
$('#loginLink').fadeOut();
}
}
</script>
</h:outputScript>
<ui:composition template="./header.xhtml">
<ui:define name="content">
<h:form>

View File

@@ -2,58 +2,188 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Pagina en construcción de Pruebas médicas">
<div class="ui-g ui-fluid">
<div class="ui-g-5 ui-md-5">
<h:form id="frmMT">
<p:panel id="mainPanel" header="Pruebas médicas">
<f:facet name="actions">
<h:commandLink rendered="#{mt.specialistDoctor}" action="#{mt.addMT}" update="frmMT,frmNEW" styleClass="ui-panel-titlebar-icon ui-corner-all ui-state-default">
<h:outputText styleClass="ui-icon pi pi-plus" />
</h:commandLink>
<h:commandLink rendered="#{mt.patSelector}" action="#{mt.clearFilteredPatient}" immediate="true" update="frmMT,frmNEW"
styleClass="ui-panel-titlebar-icon ui-corner-all ui-state-default">
<h:outputText styleClass="ui-icon pi pi-refresh" title="Quitar filtro y ver todos los registros" />
</h:commandLink>
</f:facet>
<p:autoComplete rendered="#{mt.patSelector}" id="filterPatient" widgetVar="filterPatient" dropdown="true" value="#{mt.patientFilterSelected}"
completeMethod="#{mt.completePatientFilter}" var="p" itemLabel="#{p.displayName}" itemValue="#{p}" forceSelection="true"
placeholder="Seleccione un paciente o teclee para buscar...">
<o:converter converterId="omnifaces.ListConverter" list="#{mt.patientWithTestList}" />
<f:selectItem itemLabel="Ver todos" itemValue="">
<p:column headerText="Num. Prof.">
<h:outputText value="Ver todos" />
</p:column>
</f:selectItem>
<p:column headerText="Num. Prof.">
<h:outputText value="#{p.personalIdentificationCode}" />
</p:column>
<p:column headerText="Nombre">
<h:outputText value="#{p.name}" />
</p:column>
<p:column headerText="Apellidos">
<h:outputText value="#{p.surname}" />
</p:column>
<p:ajax event="itemSelect" listener="#{mt.onSelectPatient}" update="medicalTestList" />
<p:ajax event="change" listener="#{mt.onChangePatient}" update="medicalTestList" />
</p:autoComplete>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo" value="Etiqueta para campo de formulario:" />
<p:orderList id="medicalTestList" value="#{mt.medicalTests}" var="el" itemValue="#{el}" controlsLocation="none" responsive="true">
<p:ajax event="select" listener="#{mt.onSelectMT}" update="frmNEW,frmImage" />
<o:converter converterId="omnifaces.ListConverter" list="#{mt.medicalTests}" />
<p:column>
<h:outputText value="#{el.date}">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
</h:outputText>
- <h:outputText value="#{el.type.testTypeName}" />
<br />
<h:outputText rendered="#{mt.patientFilterSelected == null}" value="#{el.patient.displayName}" style="font-size: 0.8em !important; font-style: italic;" />
</p:column>
</p:orderList>
</p:panel>
</h:form>
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo" value="Valor del campo del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
<div class="ui-g-7 ui-md-7">
<h:form id="frmImage" enctype="multipart/form-data">
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Sí" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
<p:panel rendered="#{mt.viewEdit}" id="detailPanel" header="Detalle de prueba médica">
<div class="ui-g ui-fluid">
<div class="ui-g-3">Fecha:</div>
<div class="ui-g-9">
<h:outputText value="#{mt.selected.date}">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" timeStyle="short" />
</h:outputText>
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
<div class="ui-g-3">Hora:</div>
<div class="ui-g-9">
<h:outputText value="#{mt.selected.time}" />
</div>
<div class="ui-g-3">Observaciones:</div>
<div class="ui-g-9">
<h:outputText escape="false" value="#{mt.selected.observations}" />
</div>
<div class="ui-g-3">Tipo de prueba:</div>
<div class="ui-g-9">
<h:outputText value="#{mt.selected.type.testTypeName}" />
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo2" value="Etiqueta para campo 2 de formulario:" />
<div class="ui-g-12">
<p:outputPanel rendered="#{mt.selected.type != 'BLOOD_TEST'}">
<div class="ui-g ui-fluid">
<div class="ui-g-3">Imagen de alta resolución:</div>
<div class="ui-g-5">
<p:fileUpload rendered="#{mt.specialistDoctor}" value="#{mt.imageUpload}" mode="simple" skinSimple="true" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo2" value="Valor del campo 2 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
<div class="ui-g-2">
<p:commandButton rendered="#{mt.specialistDoctor}" value="Subir" icon="pi pi-upload" ajax="false" action="#{mt.addImage}" update="frmImage" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
<div class="ui-g-2">
<p:commandButton rendered="#{mt.specialistDoctor}" value="Eliminar" icon="pi pi-trash" action="#{mt.removeImage}" disabled="#{mt.selected.highresimage == null}"
update="frmImage">
<p:confirm header="Confirme la eliminación" message="¿Está seguro de que desea eliminar la imagen?" icon="pi pi-exclamation-triangle" />
</p:commandButton>
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo3" value="Etiqueta para campo 3 de formulario:" />
<div class="ui-g-12 ui-md-12" style="align-content: center; text-align: center;">
<img src="#{mt.selected.highresimage}" style="max-width: 300px !important;" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo3" value="Valor del campo 3 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
</div>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="TestForm" action="#{BeanName.actionMethod}" icon="pi pi-check" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-4" />
</p:outputPanel>
</div>
</div>
</p:panel>
</h:form>
<h:form id="frmNEW">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel rendered="#{mt.viewCreate}" id="createPanel" header="Añadir una nueva prueba médica">
<div class="ui-g ui-fluid">
<div class="ui-g-2">Paciente:</div>
<div class="ui-g-10">
<p:autoComplete id="addTestPatient" dropdown="true" value="#{mt.patSelected}" completeMethod="#{mt.completePatient}" var="p" itemLabel="#{p.displayName}" itemValue="#{p}"
forceSelection="true" placeholder="Seleccione un paciente o teclee para buscar..." required="true"
requiredMessage="Por favor, seleccione un paciente al cual aádir la prueba.">
<o:converter converterId="omnifaces.ListConverter" list="#{mt.patientList}" />
<p:column headerText="Num. Prof.">
<h:outputText value="#{p.personalIdentificationCode}" />
</p:column>
<p:column headerText="Nombre">
<h:outputText value="#{p.name}" />
</p:column>
<p:column headerText="Apellidos">
<h:outputText value="#{p.surname}" />
</p:column>
</p:autoComplete>
</div>
<div class="ui-g-2">Fecha:</div>
<div class="ui-g-3">
<p:datePicker id="fecha" value="#{mt.testDate}" pattern="dd/MM/yyyy" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la prueba médica">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" timeStyle="short" />
</p:datePicker>
</div>
<div class="ui-g-1" />
<div class="ui-g-6">
<p:message for="fecha" />
</div>
<div class="ui-g-2">Hora:</div>
<div class="ui-g-3">
<p:datePicker id="hora" value="#{mt.testTime}" timeOnly="true" pattern="HH:mm" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la hora de la prueba médica">
<f:convertDateTime type="localTime" pattern="HH:mm" />
</p:datePicker>
</div>
<div class="ui-g-1" />
<div class="ui-g-6">
<p:message for="hora" />
</div>
<div class="ui-g-2">Observaciones:</div>
<div class="ui-g-10">
<p:textEditor value="#{mt.testObservations}" required="true" requiredMessage="Debe indicar las observaciones de la prueba" />
</div>
<div class="ui-g-2">Tipo de prueba:</div>
<div class="ui-g-5">
<p:selectOneMenu id="selUsertype" value="#{mt.testType}" required="true" unselectable="false" requiredMessage="Debe especificar un tipo de prueba médica">
<f:selectItems value="#{mt.medicalTestTypes}" var="item" itemLabel="#{item.testTypeName}" />
</p:selectOneMenu>
</div>
<div class="ui-g-1" />
<div class="ui-g-4">
<p:message for="selUsertype" />
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-4 ui-md-4">
<p:commandButton value="Guardar" action="#{mt.save}" icon="pi pi-save" update="frmMT,frmImage,frmNEW" />
</div>
<div class="ui-g-4 ui-md-4" />
</div>
</p:panel>
</h:form>
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="panelPendingQuestions" header="Listado de preguntas pendientes de respuesta">
<div class="ui-g ui-fluid">
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo" value="Etiqueta para campo de formulario:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo" value="Valor del campo del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo2" value="Etiqueta para campo 2 de formulario:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo2" value="Valor del campo 2 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo3" value="Etiqueta para campo 3 de formulario:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo3" value="Valor del campo 3 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
</div>
<p:dataTable widgetVar="dtPendingQuestions" var="qs" value="#{PendingQuestions.lazyDataModelQuestionList}" lazy="true" paginator="true" rows="10" paginatorPosition="bottom" paginatorAlwaysVisible="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="10,20,30,40">
<p:column headerText="Id" width="60px;">
<h:outputText value="#{qs.id}" />
</p:column>
<p:column headerText="Title" width="auto">
<h:outputText value="#{qs.title}"/>
</p:column>
<p:column headerText="Patient" width="auto">
<h:outputText value="#{qs.patient.displayName}" />
</p:column>
<p:column headerText="Status" width="90px;">
<h:outputText value="#{qs.status}" />
</p:column>
<p:column headerText="Acción" width="80px;">
<h:outputText value="Responder" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton type="button" icon="pi pi-refresh" onclick="PF('dtPendingQuestions').getPaginator().setPage(0);" />
</f:facet>
</p:dataTable>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="TestForm" action="#{BeanName.actionMethod}" icon="pi pi-check" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-4" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmQuestions">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="panelQuestions" header="Preguntas">
<div class="ui-g ui-fluid">
<div class="ui-g-4">
<p:panel id="panelQuestionList" header="">
<f:facet name="header">
<h:outputText rendered="#{Questions.patient}" value="Lista de preguntas realizadas" />
<h:outputText rendered="#{Questions.familyDoctor}" value="Lista de preguntas pendientes" />
</f:facet>
<f:facet name="actions">
<h:commandLink action="#{Questions.init}" immediate="true" update="frmQuestions" styleClass="ui-panel-titlebar-icon ui-corner-all ui-state-default">
<h:outputText styleClass="ui-icon pi pi-refresh" />
</h:commandLink>
<h:commandLink rendered="#{Questions.patient}" action="#{Questions.create}" update="questionDetail" styleClass="ui-panel-titlebar-icon ui-corner-all ui-state-default">
<h:outputText styleClass="ui-icon pi pi-plus" />
</h:commandLink>
</f:facet>
<p:orderList value="#{Questions.pendingQuestions}" var="pq" controlsLocation="none" itemValue="#{pq}" responsive="true">
<o:converter converterId="omnifaces.ListConverter" list="#{Questions.pendingQuestions}" />
<p:ajax event="select" listener="#{Questions.onSelect}" update="questionDetail" />
<p:ajax event="unselect" listener="#{Questions.onUnSelect}" update="questionDetail" />
<p:column>
<h:graphicImage name="images/#{pq.status}.png" alt="#{pq.status}" styleClass="ui-theme" />
</p:column>
<p:column headerText="Título">
<h:outputText value="#{pq.title}" />
</p:column>
</p:orderList>
</p:panel>
</div>
<div class="ui-g-8">
<p:outputPanel id="questionDetail">
<p:panel id="panelAddQuestion" rendered="#{Questions.addNewMode}" header="Añadir nueva pregunta">
<div class="ui-g ui-fluid">
<div class="ui-g-12">
<h3>Título:</h3>
<p:inputText value="#{Questions.selected.title}" required="true" requiredMessage="Es necesario especificar el título de la pregunta" />
</div>
<div class="ui-g-12">
<h3>Pregunta:</h3>
<p:textEditor value="#{Questions.selected.message}" required="true" requiredMessage="Es necesario especificar el texto de la pregunta" />
</div>
<div class="ui-g-4" />
<div class="ui-g-4">
<p:commandButton value="Preguntar" action="#{Questions.addNewQuestion}" update="frmQuestions" icon="pi pi-save" />
</div>
<div class="ui-g-4" />
</div>
</p:panel>
<p:panel id="panelDetail" rendered="#{Questions.showPanelDetail}" header="Pregunta de #{Questions.selected.patient.displayName}">
<!-- Responder pregunta -->
<div class="ui-g ui-fluid">
<div class="ui-g-12">
<h3>Título:</h3>
<p:inputText value="#{Questions.selected.title}" readonly="true" />
</div>
<div class="ui-g-12">
<h3>Pregunta:</h3>
<p:textEditor value="#{Questions.selected.message}" toolbarVisible="false" readonly="true" />
</div>
<div class="ui-g-12">
<h3>Respuesta:</h3>
<p:textEditor value="#{Questions.selected.response}" toolbarVisible="#{Questions.respuestaEditable}" readonly="#{not Questions.respuestaEditable}" required="true"
requiredMessage="Es necesario especificar una respuesta." />
</div>
<div class="ui-g-4" />
<div class="ui-g-4">
<p:commandButton value="Responder" rendered="#{Questions.respuestaEditable}" action="#{Questions.save}" update="frmQuestions" icon="pi pi-save" />
</div>
<div class="ui-g-4" />
</div>
</p:panel>
</p:outputPanel>
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="frmSSbD" header="Búsqueda de médicos especialista por especialidad">
<div class="ui-g ui-fluid">
<div class="ui-g-2 ui-md-2">
<p:outputLabel for="selMS" value="Especialidad:" />
</div>
<div class="ui-g-6 ui-md-6">
<p:autoComplete id="selMS" dropdown="true" required="true" value="#{sspec.medicalSpeciality}" completeMethod="#{sspec.completeMedicalSpeciality}" var="ms"
itemLabel="#{ms.displayName}" itemValue="#{ms}" forceSelection="true" requiredMessage="Por favor, selecciona una especialidad médica"
placeholder="Seleccione una especialidad médica o teclee para buscar...">
<o:converter converterId="omnifaces.ListConverter" list="#{RegisterUser.medicalSpecialtiesList}" />
<p:ajax event="itemSelect" update="dtDoctorList" onstart="PF('dtDoctorList').getPaginator().setPage(0);" />
<p:column headerText="Nombre">
<h:outputText value="#{ms.name}" />
</p:column>
<p:column headerText="Descripción">
<h:outputText value="#{ms.description}" />
</p:column>
</p:autoComplete>
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-12">
<p:dataTable id="dtDoctorList" widgetVar="dtDoctorList" var="d" value="#{sspec.lazyDataModelDoctorList}" lazy="true" paginator="true" rows="10" paginatorPosition="bottom"
paginatorAlwaysVisible="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,20,30,40" emptyMessage="No existe ningún especialista para la especialidad seleccionada.">
<p:column headerText="Núm. Profesional" width="90">
<h:outputText value="#{d.professionalNumber}" />
</p:column>
<p:column headerText="Nombre" width="150">
<h:outputText value="#{d.name}" />
</p:column>
<p:column headerText="Apellidos" width="auto">
<h:outputText value="#{d.surname}" />
</p:column>
<p:column headerText="Correo electrónico" width="auto">
<h:outputText value="#{d.email}" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton type="button" icon="pi pi-refresh" onclick="PF('dtDoctorList').getPaginator().setPage(0);" />
</f:facet>
</p:dataTable>
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -31,18 +31,18 @@
<p:panel id="PanelPHC" header="Cambiar médico de familia asignado" rendered="#{home.patient}">
<div class="ui-g ui-fluid">
<div class="ui-g-4 ui-md-4">
<div class="ui-g-2">
<p:outputLabel value="Médico de familia actualmente asignado:" />
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-4">
<p:outputLabel id="lblCurrentCenter" style="font-weight: bold;" value="#{ChangeFD.currentFamilyDoctor.displayName}" />
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-6" />
<div class="ui-g-4 ui-md-4">
<div class="ui-g-2">
<p:outputLabel value="Nuevo médico de familia:" for="newFamilyDocAC" />
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-4">
<p:autoComplete id="newFamilyDocAC" dropdown="true" required="true" value="#{ChangeFD.newFamilyDoctor}" completeMethod="#{ChangeFD.completeFamilyDoctor}" var="fd"
itemLabel="#{fd.displayName}" itemValue="#{fd}" forceSelection="true" requiredMessage="Por favor, selecciona un médico de familia"
placeholder="Seleccione su nuevo médico de familia o teclee para buscar...">
@@ -58,7 +58,7 @@
</p:column>
</p:autoComplete>
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-6">
<p:message for="newFamilyDocAC" />
</div>
@@ -73,7 +73,6 @@
<div class="ui-g-4 ui-md-4" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>

View File

@@ -31,18 +31,18 @@
<p:panel id="PanelPHC" header="Cambiar centro de antención primaria asignado" rendered="#{home.familyDoctor}">
<div class="ui-g ui-fluid">
<div class="ui-g-4 ui-md-4">
<p:outputLabel value="Centro de antención primaria actualmente asignado:" />
<div class="ui-g-2">
<p:outputLabel value="Centro de antención primaria actual:" />
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-4">
<p:outputLabel id="lblCurrentCenter" style="font-weight: bold;" value="#{ChangeCAP.currentCenter.displayName}" />
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-6" />
<div class="ui-g-4 ui-md-4">
<div class="ui-g-2">
<p:outputLabel value="Nuevo centro de atención primaria:" for="newCenter" />
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-4">
<p:autoComplete id="newCenter" dropdown="true" required="true" value="#{ChangeCAP.newCenter}" completeMethod="#{ChangeCAP.completePrimaryHealCareCenter}" var="phc"
itemLabel="#{phc.displayName}" itemValue="#{phc}" forceSelection="true" requiredMessage="Por favor, selecciona un nuevo centro de antención primaria"
placeholder="Seleccione una CAP o teclee para buscar...">
@@ -55,7 +55,7 @@
</p:column>
</p:autoComplete>
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-g-6">
<p:message for="newCenter" />
</div>

View File

@@ -35,7 +35,7 @@
<div class="ui-g-6">
<p:button value="Ir a la página principal" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-3"></div>
<div class="ui-g-3" />
</div>
</p:panel>
@@ -44,25 +44,6 @@
</h:form>
<h:form id="frmRegisterUser" rendered="#{not RegisterUser.registered}">
<h:outputScript>
function handleRequest(xhr, status, args) {
var nif = PF('nifButton');
if ( args.NIFisDupe == false ) {
nif.jq.children(".ui-icon").removeClass("pi pi-times");
nif.jq.removeClass('red-button');
nif.jq.children(".ui-icon").addClass("pi pi-check");
nif.jq.addClass('green-button');
}
else if (nif.jq.hasClass('red-button') == false) {
nif.jq.children(".ui-icon").removeClass("pi pi-check");
nif.jq.removeClass('green-button');
nif.jq.children(".ui-icon").addClass("pi pi-times");
nif.jq.addClass('red-button');
}
}
</h:outputScript>
<p:growl id="mesgs" globalOnly="true" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="tipoUsuario" header="Especifique el tipo de usuario que desea registrarse">
<div class="ui-g ui-fluid">
@@ -85,8 +66,8 @@
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-inputgroup">
<p:inputText id="nif" value="#{RegisterUser.nif}" validator="nifValidator" maxlength="20" required="true" requiredMessage="Por favor, indque su NIF">
<p:ajax event="blur" update="nifmsg" listener="#{RegisterUser.hadleNIFValueChange}" oncomplete="handleRequest(xhr, status, args)" />
<p:inputText id="nif" widgetVar="nif" value="#{RegisterUser.nif}" validator="nifValidator" maxlength="20" required="true" requiredMessage="Por favor, indque su NIF">
<p:ajax event="blur" update="nifmsg" listener="#{RegisterUser.handleNIFValueChange}" oncomplete="handleNIFResponse(xhr, status, args)" />
</p:inputText>
<p:commandButton widgetVar="nifButton" icon="pi pi-times" styleClass="red-button" />
</div>

View File

@@ -7,25 +7,6 @@
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmUpdateProfile">
<h:outputScript>
function handleRequest(xhr, status, args) {
var nif = PF('nifButton');
if ( args.NIFisDupe == false ) {
nif.jq.children(".ui-icon").removeClass("pi pi-times");
nif.jq.removeClass('red-button');
nif.jq.children(".ui-icon").addClass("pi pi-check");
nif.jq.addClass('green-button');
}
else if (nif.jq.hasClass('red-button') == false) {
nif.jq.children(".ui-icon").removeClass("pi pi-check");
nif.jq.removeClass('green-button');
nif.jq.children(".ui-icon").addClass("pi pi-times");
nif.jq.addClass('red-button');
}
}
</h:outputScript>
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="tipoUsuario" header="Tipo de usuario registrado">
@@ -60,8 +41,8 @@
</div>
<div class="ui-g-4 ui-md-4">
<div class="ui-inputgroup">
<p:inputText id="nif" value="#{UpdateProfile.nif}" validator="nifValidator" maxlength="20" required="true" requiredMessage="Por favor, indque su NIF">
<p:ajax event="blur" update="nifmsg" listener="#{UpdateProfile.hadleNIFValueChange}" oncomplete="handleRequest(xhr, status, args)" />
<p:inputText id="nif" widgetVar="nif" value="#{UpdateProfile.nif}" validator="nifValidator" maxlength="20" required="true" requiredMessage="Por favor, indque su NIF">
<p:ajax event="blur" update="nifmsg" listener="#{UpdateProfile.handleNIFValueChange}" oncomplete="handleNIFResponse(xhr, status, args)" />
</p:inputText>
<p:commandButton widgetVar="nifButton" icon="pi pi-check" styleClass="green-button" />
</div>
@@ -138,7 +119,7 @@
</div>
<div class="ui-g-4 ui-md-4">
<p:autoComplete id="selPHC" dropdown="true" value="#{UpdateProfile.primaryHealthCareCenter}" completeMethod="#{UpdateProfile.completePrimaryHealCareCenter}" var="phc"
itemLabel="#{phc.displayName}" itemValue="#{phc}" forceSelection="true" requiredMessage="Por favor, selecciona un nuevo centro de antención primaria">
itemLabel="#{phc.displayName}" itemValue="#{phc}" forceSelection="true" required="true" requiredMessage="Por favor, selecciona un nuevo centro de antención primaria">
<o:converter converterId="omnifaces.ListConverter" list="#{UpdateProfile.phcList}" />
<p:column headerText="Nombre">
<h:outputText value="#{phc.name}" />
@@ -159,12 +140,12 @@
</div>
<div class="ui-g-4 ui-md-4">
<p:autoComplete id="selMS" dropdown="true" value="#{UpdateProfile.medicalSpecialty}" completeMethod="#{UpdateProfile.completeMedicalSpecialty}" var="ms"
itemLabel="#{ms.displayName}" itemValue="#{ms}" forceSelection="true" requiredMessage="Por favor, selecciona una especialidad médica">
itemLabel="#{ms.displayName}" itemValue="#{ms}" forceSelection="true" required="true" requiredMessage="Por favor, selecciona una especialidad médica">
<o:converter converterId="omnifaces.ListConverter" list="#{UpdateProfile.medicalSpecialtiesList}" />
<p:column headerText="Nombre">
<h:outputText value="#{ms.name}" />
</p:column>
<p:column headerText="Localización">
<p:column headerText="Descripción">
<h:outputText value="#{ms.description}" />
</p:column>
</p:autoComplete>
@@ -195,6 +176,7 @@
</p:autoComplete>
</div>
<div class="ui-g-6 ui-md-6">
<p:button icon="fa fa-edit" outcome="ChangeFamilyDoctor" alt="Modificar médico de familia" />
<p:message for="FamilyDoc" />
</div>
</h:panelGroup>
@@ -202,7 +184,7 @@
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4"></div>
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="frmUpdateProfile" action="#{UpdateProfile.saveData}" icon="pi pi-check" />
<p:commandButton validateClient="true" value="Guardar" update="frmUpdateProfile,frmMenu" action="#{UpdateProfile.saveData}" icon="pi pi-check" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />

View File

@@ -1,4 +1,4 @@
BODY {
body {
font-family: Verdana, Arial, Helvetica, sans-serif;
}
@@ -11,11 +11,15 @@ BODY {
margin: 0 !important;
}
ul.ui-menu-child {
ul.ui-menu-list {
white-space: nowrap;
width: auto !important;
}
.ui-orderlist.ui-grid-responsive .ui-orderlist-list {
width: auto !important;
}
.green-button.ui-button.ui-state-default {
background-color: #5cb85c;
border-color: #5cb85c;
@@ -37,3 +41,8 @@ ul.ui-menu-child {
background-color: #d43f3a;
border-color: #d9534f;
}
.ui-orderlist .ui-orderlist-list {
height: 62vh !important;
width: 25vw !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="215.434px" height="215.434px" viewBox="0 0 215.434 215.434" enable-background="new 0 0 215.434 215.434" xml:space="preserve">
<g>
<circle fill="#54C147" cx="107.717" cy="107.717" r="106.299"/>
<polygon fill="#FFFFFF" points="96.977,121.718 145.084,50.79 168.752,69.02 103.583,164.647 46.678,120.299 63.562,96.402 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 B

View File

@@ -0,0 +1,248 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="71.337982mm"
height="65.062035mm"
viewBox="0 0 71.337982 65.062035"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="Pendiente.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="21.631587"
inkscape:cy="107.22382"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1015"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Capa 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-46.72982,-68.677315)">
<circle
style="fill:#ffdd55;fill-opacity:1;stroke-width:0.31121486"
id="path3813"
cx="81.031158"
cy="99.249031"
r="29.009672" />
<path
style="fill:#000000;stroke:none;stroke-width:0.03527778"
inkscape:connector-curvature="0"
d="m 74.462809,68.91145 c -3.457222,0.529167 -8.854723,2.504722 -12.065001,4.409722 -4.833056,2.892778 -9.771945,8.219723 -12.347223,13.370279 -1.446389,2.8575 -2.751667,7.408334 -3.139722,11.112501 -1.516945,13.864168 6.632222,27.728338 19.438057,33.196388 4.727222,2.01084 7.408333,2.54 13.052778,2.54 6.138334,0 7.231945,-0.28222 7.231945,-1.69333 v -1.02306 l -6.526389,-0.0353 c -6.385278,0 -6.596945,-0.0353 -9.877779,-1.16417 -4.691944,-1.55222 -8.396111,-3.84528 -11.818056,-7.26722 -6.0325,-6.0325 -8.960556,-12.91167 -8.995834,-21.13139 0,-11.394726 6.279445,-21.695838 16.404168,-26.775839 5.856111,-2.963333 13.687779,-3.915833 20.073057,-2.434166 9.136945,2.116666 16.93333,8.466667 20.74333,16.862778 1.23473,2.751667 2.39889,7.090834 2.39889,8.960557 0,1.199444 0.70556,2.43417 1.37584,2.43417 0.14111,0 0.56444,-0.21167 0.91722,-0.493893 0.635,-0.458611 0.635,-0.670277 0.21167,-3.421944 -0.59973,-3.880556 -2.04612,-8.149167 -3.95112,-11.465279 -1.79916,-3.175 -6.20888,-7.972778 -9.348607,-10.230556 -2.963334,-2.116667 -7.549445,-4.198056 -11.112501,-5.08 C 83.67031,68.735061 77.708365,68.417561 74.462809,68.91145 Z"
id="path3790" />
<path
style="fill:#000000;stroke:none;stroke-width:0.03527778"
inkscape:connector-curvature="0"
d="m 78.625587,74.908673 c -0.599722,0.3175 -0.635,1.199444 -0.635,10.548056 v 10.195278 l -1.023056,0.529167 c -2.434166,1.27 -3.668889,4.056946 -2.892778,6.526386 l 0.423334,1.27 -4.797778,4.62139 c -2.610556,2.54 -4.762501,4.86834 -4.762501,5.18584 0,0.67027 0.881945,1.41111 1.552223,1.23472 0.282222,-0.0706 2.645833,-2.11667 5.221111,-4.55084 3.880556,-3.66888 4.833056,-4.40972 5.397501,-4.16277 1.375833,0.52916 3.845278,0.35277 5.044722,-0.38806 3.4925,-2.15194 3.421945,-7.725833 -0.176389,-9.489722 L 80.812809,95.863674 V 85.738951 c 0,-8.713612 -0.07055,-10.195278 -0.564444,-10.65389 -0.635,-0.670277 -0.811389,-0.670277 -1.622778,-0.176388 z m 2.8575,24.518057 c 1.023056,1.30528 0.917222,2.46944 -0.3175,3.73944 -0.917222,0.88195 -1.27,1.02306 -2.2225,0.84667 -3.421945,-0.67028 -2.998611,-5.503333 0.493889,-5.503333 1.023056,0 1.481667,0.211667 2.046111,0.917223 z"
id="path3792" />
<path
style="fill:#000000;stroke:none;stroke-width:0.03527778"
inkscape:connector-curvature="0"
d="m 99.192533,104.01284 c -7.47889,2.01083 -12.347223,9.45445 -11.077223,16.93334 1.093611,6.27944 5.644445,11.04194 11.88861,12.3825 2.32834,0.49389 3.10445,0.52916 5.22111,0.17639 5.04473,-0.88195 9.2075,-3.95112 11.25361,-8.32556 2.18723,-4.69195 2.11667,-8.74889 -0.21166,-13.51139 -3.06917,-6.20889 -10.33639,-9.48972 -17.074447,-7.65528 z m 8.254997,2.99861 c 2.57528,0.9525 5.50334,3.66889 6.77334,6.24417 0.88194,1.76389 0.98777,2.39889 0.98777,5.36222 0,2.96334 -0.10583,3.59834 -0.98777,5.36222 -3.70417,7.51417 -13.58195,9.34862 -19.579171,3.66889 -2.751667,-2.57527 -3.704167,-4.62139 -3.880556,-8.32555 -0.211666,-4.445 1.164167,-7.65528 4.480278,-10.44223 3.03389,-2.54 8.254999,-3.35138 12.206109,-1.86972 z"
id="path3794" />
<circle
style="fill:#ffdd55;fill-opacity:1;stroke-width:0.13077107"
id="path3813-3"
cx="102.99097"
cy="118.6227"
r="12.189734" />
<image
y="106.07389"
x="90.484489"
id="image3875"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOAAAADhCAYAAADRcblEAAAABmJLR0QA/wD/AP+gvaeTAAAACXBI
WXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH4wwWCB4YJbjQ/wAAABl0RVh0Q29tbWVudABDcmVhdGVk
IHdpdGggR0lNUFeBDhcAACAASURBVHja7Z19fFTVue9/a+29ZybJJANJIJFgMEbUIHIsFGsLVw9e
IyCF1k8tbZVaX6CeW6niKcrRWqvo0RtfEKnoUQQ5GGsvxcMxHFo58cqlhc/HQsPxAA0oxEggMSEv
MJkJs2f23mvdPyYBQl7Iy7ztmef3V4Aws1/Wdz0v61nPYlJKkOIsaRRJoRfK0ImLpdE6BqY3Txon
RkujOUda7SNhnfJIcdoN4c+A0F1S+DQAKkQHAyABmOAZBgCd8cwOMO4Hc3iZVnAS3NPKVM8Jpo1q
YtqoBqblHmOqpw7ayFrGXQDT6PnHUYwAjJlcACaJQM1EqddNkMGjV4rAwfEyWFMsjeOKFC1gTAPA
On/dATCl8+dOSJg6CKjNzh+Mzj9bAELhH2UIACzGc2uYNvYwcxYf4mkl1cw57gBzFe7jacU6vS4C
0O6aLAI13xAd1VNFx/4pomPHJGl8DkABY45zANMGB1bEra8ZhrQT0DCc1j7umlrFXNfsUTKn/oWn
X7GXuQrpjRKACa2pUq+bYfk/vV74dk0X/h2esFVzACwt/qANGcwApAx5Gc/dyTO+9See9ffbFfc1
ewhIAjDeypaW7xbR/teZ1qkPS4VvW56UfjDmDls2lpaEsaoJSB1S+puYkl/JM2/epoyc9Qcl82tt
FEsSgLFQgbR837VO/r/vWKe2lsrTO8IxG0tLTuAuCGQAkKcBsErunvWBMnLuvyueb9aDu2ikEIAR
Uyak8UPr1M7vW23vl1r+Dzvdyix7uZQxgTEAQFZy9+zfKznf+53imeajB0MADlUzhX//ArN184+E
9z0lbOkIukHAaAF4j3sWlKujf7CNpxXTcyEAL6gcCP1es/n9u8zWDSXSqAHjntR0LyMIoxTeg9x5
zXol9861avbNreSiEoDna7II1Nxnnnh3kXXqbcaYB2AusnYRBdEEpC6l9K5RRix6QxuzaC/TRhGA
KQ5gqfDvX2w0rp4nOj4iaxdbq1ihZM57Vc1bWMkzJhCAKaa5wr9/idFQdqMIfALGc8naxQ3Eto95
2rSVWsFjW1IRxFQDcLbw73/YaCibQeAllnsqRct2nnHTC1rBw39MpYRNqgA4TXRUP2rUPztHBHaB
8TwCL2FBbNqqZM1/Thu7dFcqxIjJDmCRNJp/ZRx77m7LV0EWz14x4ttqzuKntTH/UJvMWdNkBvAJ
o+HNJ83m5xklV2wq4ZcAnlTHLF+u5s4jAG2iW6323f9sHH2gBFIHuJsGsu1BbDsI9eJfOsa9vDnZ
EjXJBOAYCL0s9OVjCyxfBZiSTwM36eLDlnJlxD3LHOMeayAAE0uLrLbKF4zjD3pStjA6ddxSL5jy
sDbu9TVK1rUEYJxVAKGvDH352G1k9VLMIFqNm5QRdy5xFD5ab+etUHYG8HbLu+s3xtFF2WT1UtYa
toG7f+645PXfcvfVtrwFbtNHvzp09Nl3Q1/+JBs8m+BLVXF3NqT5brBm3mqj4U2ygDHQFKnXvRH8
YtEUmE2U4SSdYw3bqphr8n2O4termJJJAEZB95gtW94y6h9itKBO6j0wDEgACx1F69fZxSW1iwv6
Uujos2uN+ocYU/IJPlIf5iSNgaWtDdbMe8lsepcsYASULS3fhtDhu+fI0BFyOUmDcElbt/LMeXc6
israCMChabLU68qDh+eXAAYlWkhDgNB/kDkuW+C8vHxvotaTJqoLOtdq371D/+zGkk7XggYTaQij
210ijeM79L9Nmyv1OgJwgLrXbNlSEar9gZviPdLwfTzVDWgVwc9n3iv8+wnAC+gRs3H9W0b9A2BK
AQ0eUqQgBHjOW8GaeY9YbZUUA/ahp43jKx83W1+lkjJS1CSt+me0glW/UnPnEoDn6MXQ0eW/EN73
AJ5Do4QUbQhf0i4qW6qOnk8AAngldHT5A8L7O4Bn0+ggxQrCVVr+Mw+qeXekdAxI8JHiY3mUggeM
xsdfMRvXpyyAL4aOPkvwkeILYdMzL5onNqYcgE8bx1f+QnjfIfhIcYYw/xfGV8ueNlu2pAyAj5iN
6x83W1+lhAspUSzh40b9A49Y3l2x/+4YJ2HuDe9ooHU+UuJJWvULnZdtXRvLxk+xBHCu1b67IlT7
A4KPlLgSbfOcJTu2xKopcKwAnCwCNTuCn9/kJvhIiW0GTT+YeoPrqu17Y9FrJhYxYLa0fOWhI3e4
Gc+jF0xK8IBQdUMGyoOH745JdjAWAG4IHb67c1cDFVaT7ABhWonUD2wIHV1uewBfCh1dHt5MS/CR
7CTunmOd2vCS2VJh2xjwHrOlYq1R/49UXE2yb0ho1d/rvGzrumhlRqMF4BQRqNkT/HwmI/hIdmcQ
MjDVddWuqmjsqo+OCyqNN0I1Pwl3LyORbB4RAngjeGShbWLA1aHaZVMgAxT3kZIEwbQpUt+7OhqF
25EG8HazpeJnlq+C+riQkks8+2dG01O3i47qhI0BC6TRvE+vvjabFttJyRkNmm1QPJNcE7bVJ6IF
XBmqfSibFttJyeuKqtkwm1aGjj6bcC7oIvPExtukvpfiPlKSu6Lu26xT6xZFqsNaJFzQMdJortar
r/WQ60lKEVfUC6ZOcE3cOeyTeiNhActCtQ95yPUkpZAr6oHwlxn1q+Pugt5qtmxZIPUqcj1JqeaK
LjBbXr51uB23h+eCCr1aP/C1EtrZTkpRV/Qgc142wXl5eVws4BOhYytKwNLpRZBS1RUtkXrVE9bJ
7TG3gEUiUFMT/PwmRokXUqrbQUiz2DXxz7VD2cA7VAv4K+PYrxklXkgkMEj9V0M9EHQoFnCa5d21
M/TlT2ibEYnUJdE63XnV7l2DPZ9+KBbwUaN+OWinA4l0rilLf9Q4/puou6CzrbbKOTDraNmBROoG
YNoc69Sa2dJojiqADxsNT1FDXRKpNwZ59sPG8RejBuBcs2XLDIg2etIkUu9WcIbV/v6gjsMeDIBL
zMYyOsuBROrXCnqWGE3rIw5gqdVWeSNZPxLpglbwRuvU26UDjQUHCuBio/FFgGXRAyaRLhwLLjYa
1kQMwMlW++550qihzCeJNDArOE94yydLyxcRAO8zG1fRuh+JNCg57rMG0NT3QpUwOVKva9Y/u4Fq
PkmkwUlCBka5rq5qHY4FvNdoKmeMMp8k0qAdUcjT917o0M/+ART6XcK7kVoMkkhDQtBzl9n8zpAB
nGm2VZYAIXqQJNKQAFRLRMdHM/tbkugvrbnAavlXWnq4oKdvAjCi/CJj6IHIQJS/QEupbDpj7gVm
8+Zt2pif9v7vfSRhMqVed1L/7EaFthz156L7wd03Akp0M8Si/f3YQMgzwDNuiC7fwWrIYEodV2cB
GOmauNM3GAv4Q7PtQ4UxN0HWj6Vg6dfBcemK6L699t0Q3vKoAyitejiLtiJax3B1KXjotlQbKQpE
6w+Ff/8a7r56wDHg961T7wOcAOx7xJ6Go+iFqH+N2bgq+mGAaIOauzTq8An/fojgp6lX0MHSv2+2
bund6ejl7wpER3WpNGoIsj6tRSO0sasw2N3Pg/4evQ4i8El0B6w0AfViaAX3R38yaS4H457UGzAs
rVS0v18wUAC/a538z9R8UAN0PZWs70HJLo3+gG35t6i/Byla4Lx0TfQfm+WD1Z7CS1ry9Het9t0D
AvA71qlNtPbXjxzjnopN9N62PrrvQbRBy38KzFUY/XtpqQBjKTyps/TvWCc/uiCA2SJQUyqtRqKs
L9dz3OuIxlHFPeGrRFTXYKUJ5poMNe+OmDw7s3UDwFwpDGBaqWivyL4QgLcI759B2c9eMwhQRtwJ
Jeva2AzYaK/BSi8cRS/HxpK37wb1EQIgvbeIQE2/AM60vH9I7Zmqz0RFHhzjnogN64GaqCZfziSR
tFGxAbB5A8AopwA4Zwrvn/sGUFq+UqHvoZmqR6KiCY5xL8fs+8wT/yd6yRcZgOKeFZMkEgBIoxmW
fyuNKQBgrlKr/aM+AZwq/PvyGCVfeiQqYrFGds6IhXVqXVSTL46iF2M3mTRvTu3kSzcA1TwR2DUV
Qu8VwBnWqR2U/Tw/UeGYEJM1srPJig/BmCNKrmc9tMJVMUkinXE/2zZQQce5DLK0GZavqlcArxcd
OwBo9JTOdT0vWRHT74xaAbzwQxlxNxTPtNjdi3cXIFppIHUjMO164f+0J4DSaJ5OmarurqeW/0xM
1sjOfGVHdXRKtaQJcDcchY/G9BGaTa9T8qWHtOnCt70HgJPF6c89AKPn0+V6xnCN7MyAbdkUleSL
FE1wFL2JoRyfNeTvjEUZnT3jQI8MVZ9p2NQF4DeEbw/Ff2cGbEvM1sjOmj8d1qm3I/8OhD+2SaQz
k8m/UTlj3yPsGzLwZTcAp4rTf6X4D51rZAUvx2yN7OyAjUKpVuf6ZSyTSGfiv5Pv0ITep5xTxemD
3QCcIgK7yF2QASiZ86Dmzo35V5stayNeABGrQuse8LVVxmBnvZ3dUGWK6Kg6A6BL6nWTAIUejLSg
xajQuruXuB8Rb3wcw0LrnpMJtTLpH8C0SSLwqasLwEni9GdRW3uyles5bnXU9/j1OmAjvU8uTkkk
IPpldEkz3ozPJ0Ho4AAmCr0WQAoD2FVoHcM1srPg+2BFuueLbI99EqlrMolmGV0yGUHmmiiC9eAA
JsjAvtQtwI7TGtmZeKn5/YjuPpFWI9QxZTFPInVO6zHpX5MkCE6QgS+gArhSBA+nrisgmuAsrojp
Gln3eOmtyJVqdRZaxyOJBITL6EgDleNKodeCQ+jjYbWkps8u/FBzHkRv3apiYv3ad0e8VEu75Lm4
PU7qIzsYA+gaL/VD4NLyFUvhTU3XU82DNnZJ/AZsBPfJSase2rjX45JEAqJYRpe8KpahOqgy2Kgw
lnoL8NL6G5yXfRq/7zeaYfk/REQaH3cVWsdot37vrvQmSr4MygKqijQbi7g0WpByNaCiDVr+b8DT
iuM3YJs3Ryb50pVEitFu/d6fZ5TK6JJ+HLYWqjLUgJRaguhaI8u/K66XYbWui0jy5UwSKY4yU73j
2VDfnTQuVqXRDLDUqYKRogXOoi3xhc+7C5BegOUM25KruUvjlkQ6C+Ba6iM0FC+UaWO4tNqRMkXY
ohVawYr4rJF1cz/fGX7yJYYdrfsPP6NQRpc6COZxaTSkiOkLgKXfADV3Xnwvw2iG8L8bGUseh0Lr
HpNJ62akYhIvMnKM5jBTZA1QBmJymMoF5zxtFJxXdKbrh7pjQLRBy3s8LoXWPYbQuCegZN8HauY8
JOVwaabAgxOt4fKsOK2RnS+eVgzXhI/AtKLBQ9jpesY7iXSutLFL4Lj4dUirnpAa1GysjOTJb/lM
MOfVcSvP6ptCF5xXbgJzlgwKQila4Ch8MeEes5JdCscl5WQJBydP0gMoRRO0sU8m7PU5Ly8Pn7Ar
zQFNJop7Vtyznn1C6JkGrWAFQThwuZMbQGmCZ8yMeT+UQUM4vjy8LDGAyUQd81BC34uaOw/KiDsB
4Se8Luy8ZyQ5gF5o+fcn/GUybRTUvMcB0db/ZJI2La7VOwOVo/BRasY7MLmSF0BpAmphwrprPSxH
3h2AenHfrqj0Qs1/wCbJBQ1awdPUlPeCz0nVkhhAHWrOnfZySC76p75dUZ4T12LrQceDI2cAauHA
YtvUlZq0AErph5J9s62uWRk5A+C9lKfJAJQRt9lvdI2+H5DthFk/NjA5AZQmuGty3EvOhgRhdi8J
DHkayoj/ab97GTmDELvASE1SAHUonlvs6ZNkz4KUPTOIdollu03vSiZ4xo3khvYtM0ld0CC4e4o9
fRJXYfdNutIES7/Btm+Ce2aSG9q3jKQEUEodPH28fQdt5s1nq2OkDp4+2bb3orj/DlKGCLXepXPw
jOSLbJWCmB5CGXEAM64BpNX5pxB4xlX2fReuQgAWodZ7rqKDM8WTbDcFnn6trW+BOfIBBDuteajz
z/YVd06hOLB3+TmU7CR7OAaYo9DeAzatCFIaYRiZA8wx2t4TirMYgEG49ZQ3CS2gBaaOsPc9cNfZ
szpYmv03vFK3tL6MxUnOtIuSb3bi6UlwE2cBtHM8CwBMJQD7UCtPjsF6rkJg6kh7D1imhRtlSRNJ
kSRj2jlJJdI53toJztQRyfdwbN5iQ0qDBmxKKNTEmbMAQHKt00grGfaihcITieiw/62I0ynV+nIQ
auBMyQIgk+ieHICw+fHIQj+7eC1NQNo7Rg+3viT19HRCxzhz5p9JeSeH+6kg3O3bxvwFas9mQWU7
pNDtPdAC+5AyvWcHF+vXcaZkWpE8IDL+0iD0Q/YesPqXOHtcgITUj9l7QglWUePenrLAc2o5uKsG
al4STSsq5Okd9h6wHVXnxExOiMARG1vzGgAU//WcZc0apo0BB3CYOYqSqhpGSqPzxdt00Pq2nT1p
iCkQvl02vpcqJJeHFSkZh5mjCBzAIe66Esm0GM+YG6L9E3sOWP9+dNWBhm8mDcK3xbbvwjpVQQe3
9GolrEM8fRI4gGrmujS51p2YC9bJzba8dLN1M8B6FkdYXvtZQWk0QwQ+ofivV4WqmesScAAHuKuo
+6ybBHGgCH5qOzdUWj4I7+96HnTJsmC1vGe/yaTpXTo1t88wKXSAOy8GB7CPp4+HlHpS3SDjuTC/
Wm2vAdu4Ab0elspUWP4P7TWhCB1m66t0am7f2sdcheAAdHDXPqYUJNftMRWWb7NtBq20fDBbXu6z
oS3jHltNKEbDv5D16/Nlm/t42nU6AHS1pKjiGdOGflxWwlrBPBh1j9pjwB79df8DlqXB8m2G1b47
8Y1foAZm6ytk/fp+21U8/es4F8A9PGNKUhZly+ABmCc2JvRlWie3w/JVXHDAhieUf0z40jTj6DIw
nkec9WkBA3t4xt91A/AvPGMikioR0yWeDeOrZRAd1Yn5LoxmhOoWde+E1s+EAhlA6IvEPaAldHQ5
ZOgIZT77e+cy9BfuntgNwL087VIv4EzKG2ZKAUJf3ANpNCdcoiJ4eAEYzx3EzaRBdHwMo+HNhHvO
5omNsE5toINZ+peXKfl7u5pGn21LyF07mWtiUjfPCX52a0JBGDyyELCGcEQ4z4bZ/DzMxvWJ40a3
VcL46rGBWfLUdj938oxpZ1/lOf/0JyXrJiDJliO6u28mgodmxT0zKi0fgodugwweHHKigin5ME+U
IXT02YSwfKFjPyX4Bvby/8Qzp/cK4PZwN+lg8t48UwGWhuDnM2G2VMTH6+yoRvDgbEjj+PCzhDwH
wluO4JF/gLR8cYv5wpavgOAaUPzn3a54rjs7JKXsthm3Ud9XktfrCT3JJtEKln4DHOOejtkhLkbD
mzCbnwtnCCOZpJABQJ6GNnYVlOzSmE0koaMPAWYTxXwDVxN4Rr5rwrZeLSAAVHL37NRoospzIAN7
EDx4fTihEcXUvtW+G/qB6bBaXgtbikhnCFkawHNgHH8Awc8XRDXjKy0fQkeXI3hkDmB5Cb7BTZSV
Stbs7sPwvF/ZxrNmpM5hGp0D12p5DYF9l8M4vhJSr4uQidBhndwOvXomQrW3d3Y4c0d/UgkeQfDI
HAQ/mx8u4I7QxCI6qhGqXQb9wCSI9g+iM5EkPYCnt/Gsb3Ufgue5oNnSaG4NHrweKeGG9uLKSeEF
04qhjPgeuPsaKO5JA+7LKfU6WP7/hmjfDuH/GOHGSlnxGajS7JxIHeCZM8Ezp0PxXDdwd1vosPz7
IHx7YHkrII2acKUOVbcMYxZry3Fd/d9tOKfR8vkAAsB/Bg/dVhpOEqToDCfNzmxwEFLqYMwD5poI
po4GlBHnmwbIYA1E8NPwA2Xu8P63RHp2MhCeXGQIgAWmXQ7mKAJTPN37jooOSMsLGdgDKdrAWFoY
OIIuIu4nd990s6OorNtf9zZKPlBG3lpqNr0ApOpOZqZ23rsbrOv5BY9ABo+g943LWmKn4DshYmeC
Ui9k4FPIPu4FLI2ympEH8ANlxKyer6YXC1gg9brj+mc30EsgkSLmfraOdU38r/rzw5neDuisZ67C
SjpSikSKoPuZOa++t1xCXyfk/l4ZeWvyVsWQSDEF8PTvlex5vUcHvbigAJApLd9J/cDXFCovIpGG
JQvCP9I16dNeS5X6soA+pmS+xzNuIjeURBqe+/mekn1Xn3WCvJ//Wq6O+jEgvfQQSaSh8ie85UrO
XAwFwG2KZ9pBMOrrQSINjT7zIHdN3sbTiocEIACsV7J/DAg/PUwSadAAtq9XRy3q91f6SsJ0KUca
zc169bWM1gRJpMHhB9E6yjXpYGt/v3QhC9jKtFFrlMxbk65jGokUVQn/GiVnceuFfo0P4KPeUPMW
QgpKxpBIA1fwDXX0fEQCwL08Y0IFT7uOliRIpAE5n4EKnjlv70B2nvABfuSrat7/oiUJEmkg/Im2
V7WL7h/Q7w4UwErFM+1jqIVkBUmkfukzP1bccyqZqzCiAALASu2ifyIrSCL1a/1aVqpjBt44eTAA
blFGzthOVpBE6tP6bVfcs7b0t/A+HAAB4AWt4AlI0UIPm0TqYf2aXtAKHhnU/xksgH9UPNO2cuc1
ZAVJpG70BbYqWfP/ONDYb6gAAsBz2thfkxUkkbpZP+9z2tilg/5/QwFwF3df/TZtVSKROiX8b6s5
i3cNpcHzhWpB+1KR1Otq9M9uoBpRUsobP8hAseuqXbUDbV85XAsIALXMVfikmvMg7ZQgpbj1a31S
vejJIcE3HAvYyb5Rre+fWkLtyUmpafvMg0wbO8F55aYhfwQf1gUw7Zfa2BcgrUZ6GaTU40+0/FIb
Vzasz+DDvIbNSnZpOSVkSKnnevrL1ZzFmwez6B55FzSsMdJortarr/VQQoaUIvICmOCauLNhuB/E
I3AxDUwb9bB2URkg2ujVkJLf9bQaH9YKVzRE4rN4hK5pjTp6/ibmmkyuKCnZXc9Nyoh71ihZ10bk
4yLhgnapQBrN+/Tqb2ZTM19Scpo+sw2KZ5Jrwrb6SH0kj+Dl1TNt1M+1gpcpK0pKTv5Ey88dRa/V
R/IzeYSv8bdq7tzXlKzvURMnUpK5nm2vaXmP/3a4Wc9ouqDnTBXGX/UD/2NK+BvoGGOS3U1foIo5
S77uvLw84h/No3LBTLvPcdm7Uoomenkk2+MHaPc5L3srKh/Oo3TRVTyteKF2URnFgyR702fVL3Rc
uq5qqLWe8QIQANapo+evUEbcSQXbJJvC17hCu6hsHc+YELXviE4M2F3/ETx02xxpHKd4kGQfCf9W
njnz246isqh+TSwAzJaWb2ew+u9LwNLoxZJsYPoCB5mjeLrzio1RL+3iMbidNqZkLnBcttEvrXp6
uaQEh8/0A9oC5/gNMamr5DG6rb08rfh2R+E6EISkxAbQe7tz/Ma90Uq6xAtAINxXlDKjpMRlz6pf
6Lh045bBdjazC4AAsFYdPX+ZmrMYEK30xkmJBN8yx8VvruXuq2P6vTwO9/q8NnbJM9zzI9q+REoU
+J7RCl55Xskujfl3xyIL2pdeDNUu+4XwbQF4No0CUpzga3xJy39qqZp3R1y+P54AAsArodplDxCE
pDjBt0rLf+rBeMEXLxf0XD3oKCpbxTPnkjtKij18eY/HFb5EALALwpcIQlIMY76XtPynHlTz74r7
tfAEeSZLHUVlz3DPAsqOkqIN3zNawStL4235EiUGPF+PGPWry8yWl0FtLUhRgG+Zo3Dd88rIGQlz
TYkGIADca57Y+Jbx1TJQm0NSZMgzAdm+0FG8aW00dzYkC4AAMNdqq/xt6NhP3QQhaXjwBfyAdrtz
fGwrXOwOIABMFh3V5aGa20vAXLSViTR4Cf9B5rx8gXP8hpjVdg5WPIEf316eMWG6s6RyKxQPbeol
DRK+1q08c+Z05xUbExa+RAcQANqYNurbrgnbVvDMmZQhJQ3M67TqV6h5j3/bUVSW8OtaieyCnq97
zKZ33zIaH6dDQUl9xXsS0lqoXfLmukh1riYAu2uK6Kh+I/TFjztbHtIOe9IZl7OKuabc5yh+vYop
mba5bLsB2Pmw9dWh2qU/Ex3/F+A5NPhS2uqZkKLlNS3/qfsTZXE9+QEM63bzxMbfGF8ty2Y8j7Kk
KWn1/G1Q837uKHot4h2rCcCBqUAazStDX9x/mwweoB0VqWT4rMZNyog7lzjGPWHrHid2B7BLi8zG
9S8YTU95yBomvdXzgrke1satWmOXREsqAAgAY6ReVxaqe2yB1KsoNkzOWK9czVm8TBu7pCFZbiuZ
AOzSrWbLln82Gx4pAUunTGlSWL3Wg8xx1S8dl6zYnIjlZARgry9NfyJ0bMWT1qk1jNxS27qbEsz1
pFbw9PJ49GshAIevIqnX/Sp0/Nm7RcdHYDyXQLSFuxmAFN631dyHntbG/LQWTEvaW012ALs0zWrf
/ajZ8PwcGfobwDwEYsKC17ZVyZr/nDZ26S6mjUr6W04VALs02zq5/WHjq/89A2YdgZhYFm+7kjnv
BW3Mkj8mW5xHAPbUXKutconR+OKNBGLcLd7HSuatK7UxS7akEnipDmCXSi3vrsVm4yvzhL6XYsRY
SfgBBCu450evanl3VaYieARgd00W/v33GY2rF4mObYzxbFq+iLi1MwHZLqUMrVFzH3pDHT1/byrE
eATg4JQj9bp7jabyu0T7+yWQAYBlkVUcfnx3kDuvWa/k3rlWzZndmsxZTQIwYgPHmGm1715gNr/z
I9HxkcKYG9QaY+DQQQYsAO9xz4JydfQPttm1WJoAjL8ypdH8Q7N58/etU++XSqMGBGOf0AFAJc+c
+3tlxKzfKSOm+8jaEYCRVIEI1HxXeP/8HevUf5TK0N8AsNR1U2UAkKcBOCt55swPlBGz/l3xfLM+
kXuwEIDJo2xpNN9ieT+ZaZ3aWio6PspjTANYOgAtOYGUJiB1SOltYtrllUrW7G0861t/UDK/1kaW
jgCMd8w41fL91wzh23O98G2fLkPVHkACcNrTXZUmACOcRJEhL1Pyd/L0a//E3ddtV7Ku25PKSwcE
oB3Gr+WbjWy65QAAAPBJREFULDoOfkMGDk8VHVVTRMeOSVK0gTFXJ5RKYljKM6BZAEKQMgTA2sfT
plXx9K/v4elX/YWnX7GXgCMA7S6XtHyTZODLiUKvnSD1L64U+qHxMlRbDLNOkdIAY1o4poSjE1AM
HVJpdv5gdM0IAELhH2UIACzGc2uYNvYwcxYf4mkl1cw57gBzFe7jacU6vS4CMJWsZRGMk4XS9F4s
rfYxMlifJ43m0dL05sBsGCnNEx5ped0AMiA6XGEqoXbSKgF0mjHoADrAM/xMHeVl6uiTUHJbmeo5
wbRRTUwb1QAl4xh35NdBG1nLuAsUu8VX/x83CvbHNjG9MAAAAABJRU5ErkJggg==
"
preserveAspectRatio="none"
height="25.097618"
width="25.012953" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="225.000000pt" height="225.000000pt" viewBox="0 0 225.000000 225.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,225.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M900 2009 c-98 -15 -251 -71 -342 -125 -137 -82 -277 -233 -350 -379
-41 -81 -78 -210 -89 -315 -43 -393 188 -786 551 -941 134 -57 210 -72 370
-72 174 0 205 8 205 48 l0 29 -185 1 c-181 0 -187 1 -280 33 -133 44 -238 109
-335 206 -171 171 -254 366 -255 599 0 323 178 615 465 759 166 84 388 111
569 69 259 -60 480 -240 588 -478 35 -78 68 -201 68 -254 0 -34 20 -69 39 -69
4 0 16 6 26 14 18 13 18 19 6 97 -17 110 -58 231 -112 325 -51 90 -176 226
-265 290 -84 60 -214 119 -315 144 -98 24 -267 33 -359 19z"/>
<path d="M1018 1839 c-17 -9 -18 -34 -18 -299 l0 -289 -29 -15 c-69 -36 -104
-115 -82 -185 l12 -36 -136 -131 c-74 -72 -135 -138 -135 -147 0 -19 25 -40
44 -35 8 2 75 60 148 129 110 104 137 125 153 118 39 -15 109 -10 143 11 99
61 97 219 -5 269 l-33 16 0 287 c0 247 -2 289 -16 302 -18 19 -23 19 -46 5z
m81 -695 c29 -37 26 -70 -9 -106 -26 -25 -36 -29 -63 -24 -97 19 -85 156 14
156 29 0 42 -6 58 -26z"/>
<path d="M1601 1014 c-212 -57 -350 -268 -314 -480 31 -178 160 -313 337 -351
66 -14 88 -15 148 -5 143 25 261 112 319 236 62 133 60 248 -6 383 -87 176
-293 269 -484 217z m234 -85 c73 -27 156 -104 192 -177 25 -50 28 -68 28 -152
0 -84 -3 -102 -28 -152 -105 -213 -385 -265 -555 -104 -78 73 -105 131 -110
236 -6 126 33 217 127 296 86 72 234 95 346 53z"/>
<path d="M1768 836 c-55 -15 -111 -55 -141 -102 -19 -29 -27 -34 -64 -34 -39
0 -73 -19 -73 -40 0 -18 33 -40 61 -40 26 0 29 -3 29 -30 0 -28 -3 -30 -35
-30 -39 0 -59 -24 -44 -52 7 -13 22 -18 57 -18 44 0 48 -3 69 -39 28 -48 101
-98 158 -106 65 -10 80 -4 80 30 0 27 -4 30 -42 37 -50 8 -91 28 -117 57 l-19
21 50 0 c56 0 79 16 68 50 -6 18 -15 20 -76 20 l-69 0 0 30 0 30 63 0 c65 0
87 11 87 42 0 23 -30 38 -77 38 l-38 1 32 29 c18 16 49 32 70 35 49 8 67 18
71 39 5 22 -16 46 -37 45 -9 0 -37 -6 -63 -13z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="225.000000pt" height="225.000000pt" viewBox="0 0 225.000000 225.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,225.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
</g>
</svg>

After

Width:  |  Height:  |  Size: 438 B

View File

@@ -0,0 +1,46 @@
/**
* Funciones comunes JavaScript para el proyecto MyHealth
*
*
*/
// Gestiona la ventana de login
function handleLoginRequest(xhr, status, args) {
if (args.validationFailed || !args.loggedIn) {
PF('dlgLogin').jq.effect("shake", {
times : 5
}, 100);
PF('btnLogin').enable();
} else {
PF('btnLogin').enable();
PF('dlgLogin').hide();
}
}
// Tras empezar la petición AJAX de login desabilita el botón para evitar doble login
function startLogin() {
PF('btnLogin').disable();
}
// Actualiza la interfaz tras validar si un nif está duplicado.
function handleNIFResponse(xhr, status, args) {
if (args.formattedNIF) {
var nif = PF('nif');
nif.jq.val(args.formattedNIF);
}
var nifButton = PF('nifButton');
if (args.NIFisDupe == false) {
nifButton.jq.children(".ui-icon").removeClass("pi pi-times");
nifButton.jq.removeClass('red-button');
nifButton.jq.children(".ui-icon").addClass("pi pi-check");
nifButton.jq.addClass('green-button');
} else if (nifButton.jq.hasClass('red-button') == false) {
nifButton.jq.children(".ui-icon").removeClass("pi pi-check");
nifButton.jq.removeClass('green-button');
nifButton.jq.children(".ui-icon").addClass("pi pi-times");
nifButton.jq.addClass('red-button');
}
}

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="frmListDoctors" header="Listado de médicos por Centro de Antención Primaria">
<div class="ui-g ui-fluid">
<div class="ui-g-2 ui-md-2">
<p:outputLabel for="selPHC" value="Centro de atención primaria:" />
</div>
<div class="ui-g-6 ui-md-6">
<p:autoComplete id="selPHC" dropdown="true" value="#{listDoctors.primaryHealthCareCenter}" completeMethod="#{listDoctors.completePrimaryHealCareCenter}" var="phc"
itemLabel="#{phc.displayName}" itemValue="#{phc}" forceSelection="true" required="true" requiredMessage="Por favor, seleccione un centro de antención primaria" placeholder="Seleccione un centro o escriba para buscar...">
<o:converter converterId="omnifaces.ListConverter" list="#{listDoctors.primaryHealthCareCenterList}" />
<p:ajax event="itemSelect" update="dtDoctorList" onstart="PF('dtDoctorList').getPaginator().setPage(0);" />
<p:column headerText="Nombre">
<h:outputText value="#{phc.name}" />
</p:column>
<p:column headerText="Localización">
<h:outputText value="#{phc.location}" />
</p:column>
</p:autoComplete>
</div>
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-12">
<p:dataTable id="dtDoctorList" widgetVar="dtDoctorList" var="d" value="#{listDoctors.lazyDataModelDoctorList}" lazy="true" paginator="true" rows="10"
paginatorPosition="bottom" paginatorAlwaysVisible="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="10,20,30,40"
emptyMessage="No existe ningún doctor para el centro seleccionado.">
<p:column headerText="Número Profesional" style="width:100px;">
<h:outputText value="#{d.professionalNumber}" />
</p:column>
<p:column headerText="Nombre" style="width:150px;">
<h:outputText value="#{d.name}" />
</p:column>
<p:column headerText="Apellidos" style="width:auto;">
<h:outputText value="#{d.surname}" />
</p:column>
<p:column headerText="Correo electrónico" style="width:auto;">
<h:outputText value="#{d.email}" />
</p:column>
<p:column headerText="Número de pacientes" style="width:100px; text-align: center;">
<h:outputText value="#{listDoctors.getPatientsByDoctor(d.id)}" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton type="button" icon="pi pi-refresh" onclick="PF('dtDoctorList').getPaginator().setPage(0);" />
</f:facet>
</p:dataTable>
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmListCAPs">
<p:growl id="mesgsList" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelCAPList" style="margin-bottom: 10px;" header="Gestión de Centros de Atención Primaria">
<div class="ui-g ui-fluid">
<p:dataTable widgetVar="dtCAP" var="cap" value="#{ManageHealthCareCenters.lazyDataModelCAPsList}" editable="true" lazy="true" paginator="true" rows="10" paginatorPosition="bottom" paginatorAlwaysVisible="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="10,20,30,40">
<p:ajax event="rowEdit" listener="#{ManageHealthCareCenters.onRowEdit}" update=":frmListCAPs:mesgsList" />
<p:ajax event="rowEditCancel" listener="#{ManageHealthCareCenters.onRowCancel}" update=":frmListCAPs:mesgsList" />
<p:column headerText="Nombre">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.name}" /></f:facet>
<f:facet name="input"><p:inputText value="#{cap.name}" style="width:100%" label="Nombre"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Localización">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.location}" /></f:facet>
<f:facet name="input"><p:inputText value="#{cap.location}" style="width:100%" label="Localización"/></f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:80px; text-align: center;" headerText="Editar">
<p:rowEditor />
</p:column>
<p:column style="width:80px; text-align: center;" headerText="Eliminar">
<p:commandLink class="pi pi-trash" actionListener="#{ManageHealthCareCenters.deleteDataById(cap.id)}" update=":frmListCAPs:mesgsList frmListCAPs">
<p:confirm header="Eliminar" message="¿Está seguro de que quiere borrar el centro?" icon="pi pi-exclamation-triangle"/>
</p:commandLink>
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton type="button" icon="pi pi-refresh" onclick="PF('dtCAP').getPaginator().setPage(0);" />
</f:facet>
</p:dataTable>
<p:confirmDialog global="true">
<p:commandButton value="Sí" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check"/>
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times"/>
</p:confirmDialog>
</div>
</p:panel>
</h:form>
<h:form id="frmAddCAPs">
<p:growl id="mesgsAdd" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelNewCAP" header="Alta de Centros de Atención Primaria">
<div class="ui-g ui-fluid">
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Nombre: " for="nameNew" />
</div>
<div class="ui-g-2 ui-md-2">
<p:inputText id="nameNew" value="#{ManageHealthCareCenters.name}" readonly="false" required="ManageHealthCareCenters.medicalSpecialty.name eq null"
requiredMessage="Es necesario un nombre" />
</div>
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Localización: " for="locationNew" />
</div>
<div class="ui-g-6 ui-md-6">
<p:inputText id="locationNew" value="#{ManageHealthCareCenters.location}" readonly="false" required="ManageHealthCareCenters.medicalSpecialty.location eq null"
requiredMessage="Es necesaria una localización" />
</div>
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Crear" update="mesgsAdd frmListCAPs frmAddCAPs" action="#{ManageHealthCareCenters.insertData}" icon="pi pi-check" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -6,56 +6,70 @@
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmManageSpecialties">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelMS" header="Modificación y borrado de especialidades">
<h:form id="frmEditSpecialties">
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Sí" type="button" styleClass="ui-confirmdialog-yes" icon="pi pi-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="pi pi-times" />
</p:confirmDialog>
<p:growl id="mesgsEdit" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelMS" style="margin-bottom: 10px;" header="Modificación y borrado de especialidades">
<div class="ui-g ui-fluid">
<div class="ui-g-2 ui-md-2">
<p:outputLabel for="ms"/>
<p:selectOneMenu id="ms" value="#{ManageSpecialities.medicalSpecialty}" converter="omnifaces.SelectItemsIndexConverter"
effect="fold" editable="true" filter="true" filterMatchMode="startsWith"
placeholder="- Selecciona una especialidad -">
<p:outputLabel for="ms" />
<p:selectOneMenu id="ms" value="#{ManageSpecialities.medicalSpecialty}" converter="omnifaces.SelectItemsIndexConverter" effect="fold" editable="true" filter="true"
filterMatchMode="startsWith" placeholder="- Selecciona una especialidad -">
<f:selectItems value="#{ManageSpecialities.medicalSpecialtiesList}" var="ms" itemValue="#{ms}" itemLabel="#{ms.name}" />
<f:ajax render="name description" />
</p:selectOneMenu>
</div>
<div class="ui-g-1 ui-md-1" >
<p:outputLabel value="Nombre: " for="name"/>
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Nombre: " for="name" />
</div>
<div class="ui-g-2 ui-md-2">
<p:inputText id="name" value="#{ManageSpecialities.medicalSpecialty.name}" readonly="false" required="true" requiredMessage="Es necesario un nombre" />
<p:inputText id="name" value="#{ManageSpecialities.medicalSpecialty.name}" converter="omnifaces.TrimConverter" readonly="false" required="true"
requiredMessage="Es necesario un nombre" />
</div>
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Descripción: " for="description" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="description" value="#{ManageSpecialities.medicalSpecialty.description}" readonly="false" required="true" requiredMessage="Es necesaria una descripción" />
<p:inputText id="description" value="#{ManageSpecialities.medicalSpecialty.description}" converter="omnifaces.TrimConverter" readonly="false" required="true"
requiredMessage="Es necesaria una descripción" />
</div>
<div class="ui-g-1 ui-md-1 ">
<p:commandButton validateClient="true" value="Guardar" update="mesgs" action="#{ManageSpecialities.saveData}" icon="pi pi-save" />
<p:commandButton validateClient="true" value="Guardar" update="frmEditSpecialties" action="#{ManageSpecialities.saveData}" icon="pi pi-save" />
</div>
<div class="ui-g-1 ui-md-1 ">
<p:commandButton validateClient="true" value="Borrar" update="mesgs" action="#{ManageSpecialities.deleteData}" icon="fa fa-remove" />
<p:commandButton validateClient="true" value="Borrar" update="frmEditSpecialties" action="#{ManageSpecialities.deleteData}" icon="fa fa-remove">
<p:confirm header="Confirme la eliminación" message="¿Está seguro de que desea eliminar la especialidad?" icon="pi pi-exclamation-triangle" />
</p:commandButton>
</div>
</div>
</p:panel>
</h:form>
<h:form id="frmAddSpecialties">
<p:growl id="mesgsAdd" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelNewMS" header="Alta de especialidades">
<div class="ui-g ui-fluid">
<div class="ui-g-1 ui-md-1" >
<p:outputLabel value="Nombre: " for="nameNew"/>
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Nombre: " for="nameNew" />
</div>
<div class="ui-g-2 ui-md-2">
<p:inputText id="nameNew" value="#{ManageSpecialities.name}" readonly="false" required="ManageSpecialities.medicalSpecialty.name eq null" requiredMessage="Es necesario un nombre" />
<p:inputText id="nameNew" value="#{ManageSpecialities.name}" readonly="false" required="ManageSpecialities.medicalSpecialty.name eq null"
requiredMessage="Es necesario un nombre" />
</div>
<div class="ui-g-1 ui-md-1">
<p:outputLabel value="Descripción: " for="descriptionNew" />
</div>
<div class="ui-g-6 ui-md-6">
<p:inputText id="descriptionNew" value="#{ManageSpecialities.description}" readonly="false" required="ManageSpecialities.medicalSpecialty.description eq null" requiredMessage="Es necesaria una descripción" />
<p:inputText id="descriptionNew" value="#{ManageSpecialities.description}" readonly="false" required="ManageSpecialities.medicalSpecialty.description eq null"
requiredMessage="Es necesaria una descripción" />
</div>
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Crear" update="mesgs" action="#{ManageSpecialities.insertData}" icon="pi pi-check" />
<p:commandButton validateClient="true" value="Crear" update="mesgsAdd frmAddSpecialties frmEditSpecialties" action="#{ManageSpecialities.insertData}" icon="pi pi-check" />
</div>
</div>
</p:panel>

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="visitForm">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="panelVisit" header="Detalles de la visita">
<div class="ui-g ui-fluid">
<div class="ui-g-2">
<p:outputLabel for="paciente" value="Paciente:" />
</div>
<div class="ui-g-8">
<p:inputText id="paciente" value="#{AddVisit.patient.displayName}" readonly="true" />
</div>
<div class="ui-g-2">
<p:message for="paciente" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="medico" value="Médico de familia:" />
</div>
<div class="ui-g-8">
<p:inputText id="medico" value="#{AddVisit.familyDoctor.displayName}" readonly="true" />
</div>
<div class="ui-g-2">
<p:message for="medico" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Fecha:" />
</div>
<div class="ui-g-2">
<div class="ui-inputgroup">
<p:datePicker id="fecha" widgetVar="fecha" value="#{AddVisit.date}" pattern="dd/MM/yyyy" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la visita.">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
</p:datePicker>
</div>
</div>
<div class="ui-g-8">
<p:message for="fecha" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="hora" value="Hora:" />
</div>
<div class="ui-g-2">
<p:datePicker id="hora" value="#{AddVisit.time}" timeOnly="true" pattern="HH:mm" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la hora de la visita." validatorMessage="Especifique una hora en el rango de las 06:00 a las 22:00 horas">
<f:convertDateTime type="localTime" pattern="HH:mm" />
</p:datePicker>
</div>
<div class="ui-g-8">
<p:message for="hora" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="observaciones" value="Observaciones:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="observaciones" value="#{AddVisit.observations}" />
</div>
<div class="ui-g-2">
<p:message for="observaciones" display="text" />
</div>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="visitForm" action="#{AddVisit.saveData}" icon="pi pi-check" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-4" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmPatientVisitList">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Próximas visitas agendadas">
<div class="ui-g ui-fluid">
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Ver agenda del día:" />
</div>
<div class="ui-g-3">
<div class="ui-inputgroup">
<p:datePicker id="fecha" value="#{PatientVisitList.selectedDate}" pattern="dd/MM/yyyy" showIcon="true" showButtonBar="true" autocomplete="true">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
<p:ajax event="dateSelect" listener="#{PatientVisitList.showData}" update="frmPatientVisitList" />
</p:datePicker>
<p:commandButton value="Mostrar" update="frmPatientVisitList" action="#{PatientVisitList.showData}" icon="fa calendar-alt" />
</div>
</div>
<div class="ui-g-1" />
<div class="ui-g-2">Paciente:</div>
<div class="ui-g-4">
<h:outputText rendered="#{not PatientVisitList.admin}" value="#{PatientVisitList.patient.displayName}" style="font-weight: bold;" />
<p:autoComplete rendered="#{PatientVisitList.admin}" id="filterPatient" dropdown="true" value="#{PatientVisitList.patient}"
completeMethod="#{PatientVisitList.completePatient}" var="p" itemLabel="#{p.displayName}" itemValue="#{p}" forceSelection="true"
placeholder="Seleccione un paciente o teclee para buscar...">
<o:converter converterId="omnifaces.ListConverter" list="#{PatientVisitList.patientList}" />
<p:column headerText="Num. Prof.">
<h:outputText value="#{p.personalIdentificationCode}" />
</p:column>
<p:column headerText="Nombre">
<h:outputText value="#{p.name}" />
</p:column>
<p:column headerText="Apellidos">
<h:outputText value="#{p.surname}" />
</p:column>
<p:ajax event="itemSelect" listener="#{PatientVisitList.showData}" update="frmPatientVisitList" />
</p:autoComplete>
</div>
<p:dataTable id="dtPatientVisitList" widgetVar="dtPatientVisitList" var="v" value="#{PatientVisitList.lazyDataModelVisitList}" lazy="true" paginator="true" rows="10"
paginatorPosition="bottom" paginatorAlwaysVisible="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="10,20,30,40"
emptyMessage="No existen datos para los filtros seleccionados.">
<p:column headerText="Fecha" width="90">
<h:outputText value="#{v.date}">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
</h:outputText>
</p:column>
<p:column headerText="Hora" width="60">
<h:outputText value="#{v.time}">
<f:convertDateTime type="localTime" pattern="HH:mm" />
</h:outputText>
</p:column>
<p:column headerText="Paciente" width="auto">
<h:outputText value="#{v.patient.displayName}" />
</p:column>
<p:column headerText="Observaciones" width="auto">
<h:outputText value="#{v.observations}" />
</p:column>
<p:column headerText="Resultado" width="auto">
<h:outputText value="#{v.result}" />
</p:column>
<p:column headerText="Anular" width="90">
<p:commandButton value="Anular" action="#{PatientVisitList.removeVisit(v.id)}" update="frmPatientVisitList" icon="pi pi-calendar-times" styleClass="red-button" />
</p:column>
<p:column headerText="Modificar" width="100">
<p:commandButton value="Modificar" action="#{PatientVisitList.editVisit(v.id)}" update="frmPatientVisitList" icon="pi pi-pencil" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton update="dtPatientVisitList" action="#{PatientVisitList.showData}" icon="pi pi-refresh" />
</f:facet>
</p:dataTable>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-5" />
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-5" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<f:viewParam name="id" value="#{UpdateVisit.id}" required="true" />
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="visitForm">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="panelVisit" header="Actualizar detalles de la visita">
<div class="ui-g ui-fluid">
<div class="ui-g-2">
<p:outputLabel for="paciente" value="Paciente:" />
</div>
<div class="ui-g-4">
<p:inputText id="paciente" value="#{UpdateVisit.patient.displayName}" readonly="true" />
</div>
<div class="ui-g-6">
<p:message for="paciente" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="medico" value="Médico de familia:" />
</div>
<div class="ui-g-4">
<p:inputText id="medico" value="#{UpdateVisit.familyDoctor.displayName}" readonly="true" />
</div>
<div class="ui-g-6">
<p:message for="medico" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Fecha:" />
</div>
<div class="ui-g-2">
<div class="ui-inputgroup">
<p:datePicker id="fecha" value="#{UpdateVisit.date}" pattern="dd/MM/yyyy" disabled="#{UpdateVisit.onlyResult}" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la visita." readonly="#{UpdateVisit.onlyResult}">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" timeStyle="short" />
</p:datePicker>
</div>
</div>
<div class="ui-g-8">
<p:message for="fecha" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="hora" value="Hora:" />
</div>
<div class="ui-g-2">
<p:datePicker id="hora" value="#{UpdateVisit.time}" timeOnly="true" pattern="HH:mm" disabled="#{UpdateVisit.onlyResult}" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la hora de la visita." readonly="#{UpdateVisit.onlyResult}">
<f:convertDateTime type="localTime" pattern="HH:mm" timeStyle="Short" />
</p:datePicker>
</div>
<div class="ui-g-8">
<p:message for="hora" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="observaciones" value="Observaciones:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="observaciones" value="#{UpdateVisit.observations}" readonly="#{UpdateVisit.onlyResult}" />
</div>
<div class="ui-g-2">
<p:message for="observaciones" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="resultado" value="Resultado:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="resultado" value="#{UpdateVisit.result}" readonly="#{not UpdateVisit.onlyResult}" />
</div>
<div class="ui-g-2">
<p:message for="resultado" display="text" />
</div>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="visitForm" action="#{UpdateVisit.saveData}" icon="pi pi-check" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="#{UpdateVisit.fromPage}" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-4" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="frmVisitList">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Consultar agenda del día">
<div class="ui-g ui-fluid">
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Ver agenda del día:" />
</div>
<div class="ui-g-3">
<div class="ui-inputgroup">
<p:datePicker id="fecha" value="#{VisitList.selectedDate}" pattern="dd/MM/yyyy" showIcon="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique una fecha para realizar la consulta.">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
<p:ajax event="dateSelect" listener="#{VisitList.showData}" update="frmVisitList" />
</p:datePicker>
<p:commandButton value="Mostrar" update="frmVisitList" action="#{VisitList.showData}" icon="fa calendar-alt" />
</div>
</div>
<div class="ui-g-2" />
<div class="ui-g-5">
Médico de familia:
<h:outputText value="#{VisitList.familyDoctorDisplayName}" style="font-weight: bold;" />
</div>
<p:dataTable id="dtVisitList" widgetVar="dtVisitList" var="v" value="#{VisitList.lazyDataModelVisitList}" lazy="true" paginator="true" rows="10" paginatorPosition="bottom"
paginatorAlwaysVisible="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,20,30,40" emptyMessage="No existen datos para los filtros seleccionados.">
<p:column headerText="Fecha" width="90">
<h:outputText value="#{v.date}">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
</h:outputText>
</p:column>
<p:column headerText="Hora" width="60">
<h:outputText value="#{v.time}">
<f:convertDateTime type="localTime" pattern="HH:mm" />
</h:outputText>
</p:column>
<p:column headerText="Paciente" width="auto">
<h:outputText value="#{v.patient.displayName}" />
</p:column>
<p:column headerText="Observaciones" width="auto">
<h:outputText value="#{v.observations}" />
</p:column>
<p:column headerText="Resultado" width="auto">
<h:outputText value="#{v.result}" />
</p:column>
<p:column headerText="Ver" width="80px;">
<p:commandButton value="Ver" action="#{VisitList.showVisit(v.id)}" icon="pi pi-check" />
</p:column>
<p:column headerText="Modificar" width="100px;">
<p:commandButton value="Modificar" action="#{VisitList.editVisit(v.id)}" icon="pi pi-check" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton update="dtVisitList" action="#{VisitList.showData}" icon="pi pi-refresh" />
</f:facet>
</p:dataTable>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-5" />
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-5" />
</div>
</div>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>

View File

@@ -2,52 +2,91 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
xmlns:p="http://primefaces.org/ui" xmlns:o="http://omnifaces.org/ui">
<f:viewParam name="id" value="#{VisitView.id}" required="true" />
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Pagina en construcción de Visitas">
<h:form id="visitForm">
<p:growl id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="panelVisit" header="Detalles de la visita">
<div class="ui-g ui-fluid">
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo" value="Etiqueta para campo de formulario:" />
<div class="ui-g-2">
<p:outputLabel for="paciente" value="Paciente:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo" value="Valor del campo del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
<div class="ui-g-8">
<p:inputText id="paciente" value="#{VisitView.patient.displayName}" readonly="true" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
<div class="ui-g-2">
<p:message for="paciente" display="text" />
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo2" value="Etiqueta para campo 2 de formulario:" />
<div class="ui-g-2">
<p:outputLabel for="medico" value="Médico de familia:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo2" value="Valor del campo 2 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
<div class="ui-g-8">
<p:inputText id="medico" value="#{VisitView.familyDoctor.displayName}" readonly="true" />
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
<div class="ui-g-2">
<p:message for="medico" display="text" />
</div>
<div class="ui-g-4 ui-md-4">
<p:outputLabel for="campo3" value="Etiqueta para campo 3 de formulario:" />
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Fecha:" />
</div>
<div class="ui-g-4 ui-md-4">
<p:inputText id="campo3" value="Valor del campo 3 del formulario" required="true" requiredMessage="Por favor, especifique un valor" />
<div class="ui-g-2">
<div class="ui-inputgroup">
<p:datePicker id="fecha" value="#{VisitView.date}" pattern="dd/MM/yyyy" showIcon="true" disabled="true" showButtonBar="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la visita.">
<f:convertDateTime type="localDate" pattern="dd/MM/yyyy" />
</p:datePicker>
</div>
<div class="ui-g-4 ui-md-4">
<p:message for="campo" display="text" />
</div>
<div class="ui-g-8">
<p:message for="fecha" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="hora" value="Hora:" />
</div>
<div class="ui-g-2">
<p:datePicker id="hora" value="#{VisitView.time}" timeOnly="true" pattern="HH:mm" showIcon="true" showButtonBar="true" autocomplete="true" disabled="true" required="true"
requiredMessage="Especifique la hora de la visita.">
<f:convertDateTime type="localTime" pattern="HH:mm" />
</p:datePicker>
</div>
<div class="ui-g-8">
<p:message for="hora" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="observaciones" value="Observaciones:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="observaciones" value="#{VisitView.observations}" readonly="true" />
</div>
<div class="ui-g-2">
<p:message for="observaciones" display="text" />
</div>
<div class="ui-g-2">
<p:outputLabel for="resultado" value="Resultado:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="resultado" value="#{VisitView.result}" readonly="true" />
</div>
<div class="ui-g-2">
<p:message for="resultado" display="text" />
</div>
<div class="ui-g-12 ui-g-nopad">
<div class="ui-g-4 ui-md-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Guardar" update="TestForm" action="#{BeanName.actionMethod}" icon="pi pi-check" />
<p:commandButton value="Editar" action="#{VisitView.editVisit(VisitView.id)}" icon="pi pi-time" />
</div>
<div class="ui-g-2 ui-md-2">
<p:button value="Volver" outcome="/home" icon="pi pi-home" />
<p:button value="Volver" outcome="#{VisitView.fromPage}" icon="pi pi-home" />
</div>
<div class="ui-g-4 ui-md-4" />
</div>

View File

@@ -0,0 +1,13 @@
{
"apps" : [{
"name": "ANT",
"script": "start.sh",
"cwd": "./",
"ignore_watch": ["*.ear", "*.jar", "*.war", "./build/*", "./dist/*", "ecosystem.json"],
"watch": true
},{
"name": "Widlfly",
"script": "standalone.sh",
"cwd": "/opt/wildfly/bin/"
}]
}

View File

@@ -1,4 +1,7 @@
<application>
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd" version="6">
<application-name>MyHealth</application-name>
<display-name>MyHealth</display-name>
<module>
<web>
@@ -10,4 +13,3 @@
<ejb>MyHealth.jar</ejb>
</module>
</application>

View File

@@ -18,18 +18,19 @@ public class LoggedUserTO implements Serializable {
private String id;
private String password;
private String name;
private String displayName;
private UserType userType;
public LoggedUserTO() {
super();
}
public LoggedUserTO(String usrId, String usrName, String usrPwd, UserType usrType) {
public LoggedUserTO(String usrId, String usrName, String usrPwd, UserType usrType, String dispName) {
id = usrId;
name = usrName;
password = usrPwd;
userType = usrType;
displayName = dispName;
}
public String getId() {
@@ -64,4 +65,12 @@ public class LoggedUserTO implements Serializable {
this.userType = value;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}

View File

@@ -1,10 +1,13 @@
package TO;
import java.io.Serializable;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalTime;
import javax.xml.bind.annotation.XmlRootElement;
import common.MedicalTestType;
/**
*
* @author Roberto Orden Erena <rorden@uoc.edu>
@@ -16,19 +19,24 @@ public class MedicalTestTO implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private Date date;
private long time;
private LocalDate date;
private LocalTime time;
private String observations;
private String highresimage;
private MedicalTestType type;
private PatientTO patient;
private SpecialistDoctorTO specialistDoctor;
public static enum MedicalTestType {
BLOD_TEST, MAGNETIC_RESONANCE, TAC
public MedicalTestTO() {
super();
this.date = LocalDate.now();
this.time = LocalTime.now();
this.patient = new PatientTO();
this.specialistDoctor = new SpecialistDoctorTO();
}
public MedicalTestTO(int id, Date date, int time, String observations, String highresimage, MedicalTestType type,
public MedicalTestTO(int id, LocalDate date, LocalTime time, String observations, String highresimage, MedicalTestType type,
PatientTO patiend, SpecialistDoctorTO specialistDoctor) {
this.setId(id);
this.setDate(date);
@@ -48,19 +56,19 @@ public class MedicalTestTO implements Serializable {
this.id = id;
}
public Date getDate() {
public LocalDate getDate() {
return date;
}
public void setDate(Date date) {
public void setDate(LocalDate date) {
this.date = date;
}
public long getTime() {
public LocalTime getTime() {
return time;
}
public void setTime(long time) {
public void setTime(LocalTime time) {
this.time = time;
}
@@ -104,4 +112,8 @@ public class MedicalTestTO implements Serializable {
this.specialistDoctor = specialistDoctor;
}
@Override
public String toString() {
return Integer.toString(this.getId());
}
}

View File

@@ -4,8 +4,6 @@ import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;
import jpa.FamilyDoctorJPA;
/**
*
* @author Marcos García Núñez (mgarcianun@uoc.edu)

View File

@@ -27,6 +27,8 @@ public class QuestionTO implements Serializable {
public QuestionTO() {
super();
this.patient = new PatientTO();
this.fdoctor = new FamilyDoctorTO();
}
public QuestionTO(int id, String title, String message, QuestionStatus status, PatientTO patient,
@@ -97,4 +99,20 @@ public class QuestionTO implements Serializable {
this.response = response;
}
public String toString() {
return "{"
+ "ObjectID" + super.toString()
+ ",id" + this.getId()
+ ",title" + this.getTitle()
+ ",message" + this.getMessage()
+ ",response" + this.getResponse()
+ ",status" + this.getStatus()
+ ",patient-id" + this.getPatient().getId()
+ ",patient-name-surname" + this.getPatient().getName() + " " + this.getPatient().getSurname()
+ ",fdoctor-id" + this.getDoctor().getId()
+ ",fdoctor-name-surname" + this.getDoctor().getName() + " " + this.getDoctor().getSurname()
+ "}";
}
}

View File

@@ -1,18 +1,15 @@
package TO;
import java.io.Serializable;
import java.sql.Time;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalTime;
import javax.xml.bind.annotation.XmlRootElement;
/**
* Transfer object (TO) MedicalSpecialtyTO Para el intercambio de datos entre la
* capa de interfaz y la capa de negocio
* Transfer object (TO) MedicalSpecialtyTO Para el intercambio de datos entre la capa de interfaz y la capa de negocio
*
* Además esta clase facilita la implementación futura de una Capa SOA (Se
* define la anotación para la serialización de esta clase: @XmlRootElement(name
* = "medicalspeciality")
* Además esta clase facilita la implementación futura de una Capa SOA (Se define la anotación para la serialización de esta clase: @XmlRootElement(name = "medicalspeciality")
*
* @author mark
*
@@ -20,12 +17,10 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Visit")
public class VisitTO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Date date;
private Time time;
private LocalDate date;
private LocalTime time;
private String observations;
private String result;
private FamilyDoctorTO familyDoctor;
@@ -34,33 +29,39 @@ public class VisitTO implements Serializable {
public VisitTO() {
super();
}
public VisitTO(Integer id, Date date, Time time, String observation, String result) {
this.setId(id);
this.date=date;
//this.time
public VisitTO(Integer Id, LocalDate date, LocalTime time, String observations, String result, FamilyDoctorTO fd, PatientTO pat) {
this.id = Id;
this.date = date;
this.time = time;
this.observations = observations;
this.result = result;
this.familyDoctor = fd;
this.patient = pat;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id=id;
this.id = id;
}
public Date getDate() {
public LocalDate getDate() {
return this.date;
}
public void setDate(Date date) {
this.date=date;
public void setDate(LocalDate date) {
this.date = date;
}
public Time getTime() {
public LocalTime getTime() {
return this.time;
}
public void setTime(Time time) {
this.time=time;
public void setTime(LocalTime time) {
this.time = time;
}
public String getObservations() {
@@ -68,8 +69,31 @@ public class VisitTO implements Serializable {
}
public void setObservations(String observations) {
this.observations=observations;
this.observations = observations;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public FamilyDoctorTO getFamilyDoctor() {
return familyDoctor;
}
public void setFamilyDoctor(FamilyDoctorTO familyDoctor) {
this.familyDoctor = familyDoctor;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
}

View File

@@ -6,7 +6,7 @@ package common;
*
*/
public class Constants {
public static final int MAX_ITEMS_AUTOCOMPLETE_SEARCH = 200;
public static final int MAX_ITEMS_AUTOCOMPLETE_SEARCH = 20;
public static final String PROFESSIONAL_NUMBER_PREFIX = "PRO#";
public static final String PERSONAL_IDENTIFICATION_CODE_PREFIX = "PAT#";

View File

@@ -5,12 +5,12 @@ package common;
* @author Marcos García Núñez (mgarcianun@uoc.edu)
*
*/
public enum TestType {
public enum MedicalTestType {
MAGNETIC_RESONANCE_IMAGING("Imagen por Resonancia Magnética"), CT_SCAN("Tomografía Áxial Computerizada"), BLOOD_TEST("Análisis de sangre");
private String testTypeName;
private TestType(String typeName) {
private MedicalTestType(String typeName) {
this.testTypeName = typeName;
}

View File

@@ -6,7 +6,7 @@ package common;
*
*/
public enum QuestionStatus {
ANSWERED("Respondida"), PENDING("Pendiente");
ANSWERED("Respondida"), PENDING("Pendiente"), NEW("New");
private String questionStatusName;

View File

@@ -10,17 +10,21 @@ import javax.persistence.TypedQuery;
import TO.FamilyDoctorTO;
import TO.MedicalSpecialtyTO;
import TO.MedicalTestTO;
import TO.PatientTO;
import TO.PrimaryHealthCareCenterTO;
import TO.QuestionTO;
import TO.SpecialistDoctorTO;
import TO.VisitTO;
import common.Utils;
import jpa.FamilyDoctorJPA;
import jpa.MedicalSpecialtyJPA;
import jpa.MedicalTestJPA;
import jpa.PatientJPA;
import jpa.PrimaryHealthCareCenterJPA;
import jpa.QuestionJPA;
import jpa.SpecialistDoctorJPA;
import jpa.VisitJPA;
/***
*
@@ -34,7 +38,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
private EntityManager entman;
/**
* Metodo que devuelve todas las especialidades medicas registradas en el sistema
* Metodo que devuelve todas las especialidades medicas registradas en el
* sistema
*
* @return Devuelve una Lista de MedicalSpecialtyTO (Transfer Objects).
*/
@@ -45,9 +50,11 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
/**
* Metodo que devuelve las especialidades médicas de forma paginada
*
* Acepta como parametro la página (comenzando en 0) y el número de elementos de cada página.
* Acepta como parametro la página (comenzando en 0) y el número de elementos de
* cada página.
*
* si pageSize == 0, entonces se devuelven todas las especialidades registradas (Se ignora el parámetro).
* si pageSize == 0, entonces se devuelven todas las especialidades registradas
* (Se ignora el parámetro).
*
* @return Devuelve una Lista de MedicalSpecialtyTO (Transfer Objects).
*/
@@ -56,12 +63,15 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista de espcialidades médicas que tienen una coincidencia parcial en el nombre o en la descripción con el termino de búsqueda (searchTerm)
* especificado.
* Método que devuelve una lista de espcialidades médicas que tienen una
* coincidencia parcial en el nombre o en la descripción con el termino de
* búsqueda (searchTerm) especificado.
*
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza
* paginación y se devuelven todos los resultados.
*
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el parámetro y devuelven todas las especialidades existentes.
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el
* parámetro y devuelven todas las especialidades existentes.
*
* @return Devuelve una Lista de MedicalSpecialtyTO (Transfer Objects).
*/
@@ -77,7 +87,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
strFilter = "WHERE lower(ms.name) LIKE :searchTerm OR lower(ms.description) LIKE :searchTerm";
}
TypedQuery<MedicalSpecialtyJPA> query = entman.createQuery(String.format(strQuery, strFilter), MedicalSpecialtyJPA.class);
TypedQuery<MedicalSpecialtyJPA> query = entman.createQuery(String.format(strQuery, strFilter),
MedicalSpecialtyJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
@@ -107,9 +118,11 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista de CAPs (Centros de Atención Primarios) de forma paginada
* Método que devuelve una lista de CAPs (Centros de Atención Primarios) de
* forma paginada
*
* Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
* Si pageSize == 0 no se realiza paginación y se devuelven todos los
* resultados.
*
* @return Devuelve una Lista de MedicalSpecialtyTO (Transfer Objects).
*/
@@ -118,12 +131,15 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista de CAPs (Centros de Atención Primarios) que tienen una coincidencia parcial en el nombre o en la localización con el termino de búsqueda
* (searchTerm) especificado.
* Método que devuelve una lista de CAPs (Centros de Atención Primarios) que
* tienen una coincidencia parcial en el nombre o en la localización con el
* termino de búsqueda (searchTerm) especificado.
*
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza
* paginación y se devuelven todos los resultados.
*
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el parámetro y devuelven todos los CAPs existentes.
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el
* parámetro y devuelven todos los CAPs existentes.
*
* @return Devuelve una Lista de PrimaryHealthCareCenterTO (Transfer Objects).
*/
@@ -139,7 +155,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
strFilter = "WHERE lower(phc.name) LIKE :searchTerm OR lower(phc.location) LIKE :searchTerm";
}
TypedQuery<PrimaryHealthCareCenterJPA> query = entman.createQuery(String.format(strQuery, strFilter), PrimaryHealthCareCenterJPA.class);
TypedQuery<PrimaryHealthCareCenterJPA> query = entman.createQuery(String.format(strQuery, strFilter),
PrimaryHealthCareCenterJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
@@ -160,7 +177,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista con todos los médicos de familia registrados en el sistema.
* Método que devuelve una lista con todos los médicos de familia registrados en
* el sistema.
*
* @return Devuelve una Lista de FamilyDoctorTO (Transfer Objects).
*/
@@ -169,9 +187,11 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista con todos los médicos de familia registrados en el sistema de forma paginada.
* Método que devuelve una lista con todos los médicos de familia registrados en
* el sistema de forma paginada.
*
* Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
* Si pageSize == 0 no se realiza paginación y se devuelven todos los
* resultados.
*
* @return Devuelve una Lista de FamilyDoctorTO (Transfer Objects).
*/
@@ -180,11 +200,15 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que devuelve una lista de médicos de familia que tienen una coincidencia parcial en el nombre o en los apellidos con el termino de búsqueda (searchTerm) especificado.
* Método que devuelve una lista de médicos de familia que tienen una
* coincidencia parcial en el nombre o en los apellidos con el termino de
* búsqueda (searchTerm) especificado.
*
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza
* paginación y se devuelven todos los resultados.
*
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el parámetro y devuelven todos los registros existentes.
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el
* parámetro y devuelven todos los registros existentes.
*
* @return Devuelve una Lista de FamilyDoctorTO (Transfer Objects).
*/
@@ -200,7 +224,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
strFilter = "WHERE lower(fd.name) LIKE :searchTerm OR lower(fd.surname) LIKE :searchTerm";
}
TypedQuery<FamilyDoctorJPA> query = entman.createQuery(String.format(strQuery, strFilter), FamilyDoctorJPA.class);
TypedQuery<FamilyDoctorJPA> query = entman.createQuery(String.format(strQuery, strFilter),
FamilyDoctorJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
@@ -221,7 +246,60 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que convierte un objecto de tipo MedicalSpecialtyJPA (JPA) a su equivalente MedicalSpecialtyTO (Tranfer Object)
* Método que devuelve una lista con todos los pacientes registrados en el sistema de forma paginada.
*
* Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
*
* @return Devuelve una Lista de PatientTO (Transfer Objects).
*/
public List<PatientTO> listPatientsPaged(int pageNumber, int pageSize) {
return this.listPatientsFiltered(null, pageNumber, pageSize);
}
/**
* Método que devuelve una lista de pacientes que tienen una coincidencia parcial en el nombre o en los apellidos con el termino de búsqueda (searchTerm) especificado.
*
* Además permite la paginacción de datos. Si pageSize == 0 no se realiza paginación y se devuelven todos los resultados.
*
* Si serachTerm es nulo o cadena vacía entonces no se tiene en cuenta el parámetro y devuelven todos los registros existentes.
*
* @return Devuelve una Lista de PatientTO (Transfer Objects).
*/
public List<PatientTO> listPatientsFiltered(String searchTerm, int pageNumber, int pageSize) {
String strQuery = "SELECT p FROM PatientJPA p %s order by p.name, p.surname";
String strFilter = "";
if (searchTerm == null)
searchTerm = "";
else
searchTerm = Utils.normalizeTerm(searchTerm);
if (searchTerm.length() > 0) {
strFilter = "WHERE lower(p.name) LIKE :searchTerm OR lower(p.surname) LIKE :searchTerm";
}
TypedQuery<PatientJPA> query = entman.createQuery(String.format(strQuery, strFilter), PatientJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<PatientJPA> allPAsJPA = query.getResultList();
List<PatientTO> allPATOs = new ArrayList<PatientTO>();
for (PatientJPA item : allPAsJPA) {
allPATOs.add(this.getPOJOforPatientJPA(item, 0));
}
return allPATOs;
}
/**
* Método que convierte un objecto de tipo MedicalSpecialtyJPA (JPA) a su
* equivalente MedicalSpecialtyTO (Tranfer Object)
*
* @return MedicalSpecialtyTO (Transfer Object de una especialidad médica)
*/
@@ -236,7 +314,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que convierte un objecto de tipo PrimaryHealthCareCenterJPA (JPA) a su equivalente PrimaryHealthCareCenterTO (Tranfer Object)
* Método que convierte un objecto de tipo PrimaryHealthCareCenterJPA (JPA) a su
* equivalente PrimaryHealthCareCenterTO (Tranfer Object)
*
* @return PrimaryHealthCareCenterTO (Transfer Object de un CAP)
*/
@@ -251,10 +330,14 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que convierte un objecto de tipo SpecialistDoctorJPA (JPA) a su equivalente SpecialistDoctorTO (Tranfer Object)
* Método que convierte un objecto de tipo SpecialistDoctorJPA (JPA) a su
* equivalente SpecialistDoctorTO (Tranfer Object)
*
* El parámetro nestedProps es un valor entero que indica a que nivel de profundidad se debe navegar a través de las propiedades relacionadas para convertirlas de JPA a TO. Un
* valor 0 indica que no se convertirá ninguna propiedad que tenga un entidad JPA relacionada (tendrá valor null en el objeto TO).
* El parámetro nestedProps es un valor entero que indica a que nivel de
* profundidad se debe navegar a través de las propiedades relacionadas para
* convertirlas de JPA a TO. Un valor 0 indica que no se convertirá ninguna
* propiedad que tenga un entidad JPA relacionada (tendrá valor null en el
* objeto TO).
*
* @return SpecialistDoctorTO (Transfer Object de un médico especialista)
*/
@@ -267,18 +350,22 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
ms = sd.getMedicalSpecialty();
nestedProps--;
sdTO = new SpecialistDoctorTO(sd.getId(), sd.getProfessionalNumber(), sd.getNif(), sd.getName(), sd.getSurname(), sd.getPassword(), sd.getEmail(),
this.getPOJOforMedicalSpecialtyJPA(ms));
sdTO = new SpecialistDoctorTO(sd.getId(), sd.getProfessionalNumber(), sd.getNif(), sd.getName(),
sd.getSurname(), sd.getPassword(), sd.getEmail(), this.getPOJOforMedicalSpecialtyJPA(ms));
}
return sdTO;
}
/**
* Método que convierte un objecto de tipo FamilyDoctorJPA (JPA) a su equivalente FamilyDoctorTO (Tranfer Object)
* Método que convierte un objecto de tipo FamilyDoctorJPA (JPA) a su
* equivalente FamilyDoctorTO (Tranfer Object)
*
* El parámetro nestedProps es un valor entero que indica a que nivel de profundidad se debe navegar a través de las propiedades relacionadas para convertirlas de JPA a TO. Un
* valor 0 indica que no se convertirá ninguna propiedad que tenga un entidad JPA relacionada (tendrá valor null en el objeto TO).
* El parámetro nestedProps es un valor entero que indica a que nivel de
* profundidad se debe navegar a través de las propiedades relacionadas para
* convertirlas de JPA a TO. Un valor 0 indica que no se convertirá ninguna
* propiedad que tenga un entidad JPA relacionada (tendrá valor null en el
* objeto TO).
*
* @return FamilyDoctorTO (Transfer Object de un médico especialista)
*/
@@ -291,18 +378,22 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
phc = fd.getPrimaryHealthCareCenter();
nestedProps--;
fdTO = new FamilyDoctorTO(fd.getId(), fd.getProfessionalNumber(), fd.getNif(), fd.getName(), fd.getSurname(), fd.getPassword(), fd.getEmail(),
this.getPOJOforPrimaryHealthCareCenterJPA(phc));
fdTO = new FamilyDoctorTO(fd.getId(), fd.getProfessionalNumber(), fd.getNif(), fd.getName(),
fd.getSurname(), fd.getPassword(), fd.getEmail(), this.getPOJOforPrimaryHealthCareCenterJPA(phc));
}
return fdTO;
}
/**
* Método que convierte un objecto de tipo PatientJPA (JPA) a su equivalente PatientTO (Tranfer Object)
* Método que convierte un objecto de tipo PatientJPA (JPA) a su equivalente
* PatientTO (Tranfer Object)
*
* El parámetro nestedProps es un valor entero que indica a que nivel de profundidad se debe navegar a través de las propiedades relacionadas para convertirlas de JPA a TO. Un
* valor 0 indica que no se convertirá ninguna propiedad que tenga un entidad JPA relacionada (tendrá valor null en el objeto TO).
* El parámetro nestedProps es un valor entero que indica a que nivel de
* profundidad se debe navegar a través de las propiedades relacionadas para
* convertirlas de JPA a TO. Un valor 0 indica que no se convertirá ninguna
* propiedad que tenga un entidad JPA relacionada (tendrá valor null en el
* objeto TO).
*
* @return PatientTO (Transfer Object de un médico especialista)
*/
@@ -315,7 +406,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
fd = pat.getFamilyDoctor();
nestedProps--;
paTO = new PatientTO(pat.getId(), pat.getPersonalIdentificationCode(), pat.getNif(), pat.getName(), pat.getSurname(), pat.getPassword(), pat.getEmail(),
paTO = new PatientTO(pat.getId(), pat.getPersonalIdentificationCode(), pat.getNif(), pat.getName(),
pat.getSurname(), pat.getPassword(), pat.getEmail(),
this.getPOJOforFamilyDoctorJPA(fd, nestedProps));
}
@@ -323,9 +415,11 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que recupera un paciente a partir de su Identificador (Id) de base de datos.
* Método que recupera un paciente a partir de su Identificador (Id) de base de
* datos.
*
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se
* encuentra el objeto buscado
*/
public PatientTO findPatientById(int patientId) {
// Recuperamos propiedades anidadas 1 nivel!
@@ -333,12 +427,15 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que recupera un paciente a partir de su CIP (Código de Identificación de Paciente)
* Método que recupera un paciente a partir de su CIP (Código de Identificación
* de Paciente)
*
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se
* encuentra el objeto buscado
*/
public PatientTO findPatientByCode(String code) {
TypedQuery<PatientJPA> query = entman.createQuery("from PatientJPA pat where pat.personalIdentificationCode=:code", PatientJPA.class);
TypedQuery<PatientJPA> query = entman
.createQuery("from PatientJPA pat where pat.personalIdentificationCode=:code", PatientJPA.class);
query.setMaxResults(1);
query.setParameter("code", code);
@@ -352,7 +449,8 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
/**
* Método que recupera un paciente a partir de su NIF
*
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return PatientTO (Transfer Object del objeto recuperado) o null si no se
* encuentra el objeto buscado
*/
public PatientTO findPatientByNif(String searchedNIF) {
TypedQuery<PatientJPA> query = entman.createQuery("from PatientJPA pat where pat.nif=:nif", PatientJPA.class);
@@ -367,21 +465,26 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que recupera un médico de familia a partir de su Identificador (Id) de base de datos.
* Método que recupera un médico de familia a partir de su Identificador (Id) de
* base de datos.
*
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no
* se encuentra el objeto buscado
*/
public FamilyDoctorTO findFamilyDoctorById(int ProfessionalNumberId) {
return this.getPOJOforFamilyDoctorJPA(entman.find(FamilyDoctorJPA.class, ProfessionalNumberId), 1);
}
/**
* Método que recupera un médico de familia a partir de su NP (Número de profesional)
* Método que recupera un médico de familia a partir de su NP (Número de
* profesional)
*
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no
* se encuentra el objeto buscado
*/
public FamilyDoctorTO findFamilyDoctorByCode(String code) {
TypedQuery<FamilyDoctorJPA> query = entman.createQuery("from FamilyDoctorJPA d where d.professionalNumber=:code", FamilyDoctorJPA.class);
TypedQuery<FamilyDoctorJPA> query = entman
.createQuery("from FamilyDoctorJPA d where d.professionalNumber=:code", FamilyDoctorJPA.class);
query.setParameter("code", code);
@@ -395,10 +498,12 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
/**
* Método que recupera un médico de familia a partir de su NIF
*
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return FamilyDoctorTO (Transfer Object del objeto recuperado) o null si no
* se encuentra el objeto buscado
*/
public FamilyDoctorTO findFamilyDoctorByNif(String searchedNIF) {
TypedQuery<FamilyDoctorJPA> query = entman.createQuery("from FamilyDoctorJPA d where d.nif=:nif", FamilyDoctorJPA.class);
TypedQuery<FamilyDoctorJPA> query = entman.createQuery("from FamilyDoctorJPA d where d.nif=:nif",
FamilyDoctorJPA.class);
query.setMaxResults(1);
query.setParameter("nif", searchedNIF);
@@ -410,21 +515,26 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que recupera un médico especialista a partir de su Identificador (Id) de base de datos.
* Método que recupera un médico especialista a partir de su Identificador (Id)
* de base de datos.
*
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si
* no se encuentra el objeto buscado
*/
public SpecialistDoctorTO findSpecialistDoctorById(int ProfessionalNumberId) {
return this.getPOJOforSpecialistDoctorJPA(entman.find(SpecialistDoctorJPA.class, ProfessionalNumberId), 1);
}
/**
* Método que recupera un médico especialista a partir de su NP (Número de profesional)
* Método que recupera un médico especialista a partir de su NP (Número de
* profesional)
*
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si
* no se encuentra el objeto buscado
*/
public SpecialistDoctorTO findSpecialistDoctorByCode(String code) {
TypedQuery<SpecialistDoctorJPA> query = entman.createQuery("from SpecialistDoctorJPA d where d.professionalNumber=:code", SpecialistDoctorJPA.class);
TypedQuery<SpecialistDoctorJPA> query = entman
.createQuery("from SpecialistDoctorJPA d where d.professionalNumber=:code", SpecialistDoctorJPA.class);
query.setParameter("code", code);
@@ -438,10 +548,11 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
/**
* Método que recupera un médico especialista a partir de su NIF
*
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return SpecialistDoctorTO (Transfer Object del objeto recuperado) o null si el objeto JPA es nulo
*/
public SpecialistDoctorTO findSpecialistDoctorByNif(String searchedNIF) {
TypedQuery<SpecialistDoctorJPA> query = entman.createQuery("from SpecialistDoctorJPA d where d.nif=:nif", SpecialistDoctorJPA.class);
TypedQuery<SpecialistDoctorJPA> query = entman.createQuery("from SpecialistDoctorJPA d where d.nif=:nif",
SpecialistDoctorJPA.class);
query.setMaxResults(1);
query.setParameter("nif", searchedNIF);
@@ -453,12 +564,13 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
/**
* Método que convierte un objecto de tipo QuestionJPA (JPA) a su equivalente QuestionTO (Tranfer Object)
* Método que convierte un objecto de tipo QuestionJPA (JPA) a su equivalente
* QuestionTO (Tranfer Object)
*
* El parámetro nestedProps es un valor entero que indica a que nivel de profundidad se debe navegar a través de las propiedades relacionadas para convertirlas de JPA a TO. Un
* valor 0 indica que no se convertirá ninguna propiedad que tenga un entidad JPA relacionada (tendrá valor null en el objeto TO).
*
* @return QuestionTO (Transfer Object del objeto recuperado) o null si no se encuentra el objeto buscado
* @return QuestionTO (Transfer Object del objeto recuperado) o null si el objeto JPA es nulo
*/
public QuestionTO getPOJOforQuestionJPA(QuestionJPA qs, int nestedProps) {
QuestionTO qsTO = null;
@@ -472,11 +584,57 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
}
nestedProps--;
qsTO = new QuestionTO(qs.getId(), qs.getTitle(), qs.getMessage(), qs.getStatus(), this.getPOJOforPatientJPA(pat, nestedProps),
this.getPOJOforFamilyDoctorJPA(fd, nestedProps), qs.getResponse());
qsTO = new QuestionTO(qs.getId(), qs.getTitle(), qs.getMessage(), qs.getStatus(),
this.getPOJOforPatientJPA(pat, nestedProps), this.getPOJOforFamilyDoctorJPA(fd, nestedProps),
qs.getResponse());
}
return qsTO;
}
/**
* Método que converite un objeto de tipo VisitJPA a su equivalente VisitTO (Transfer Object)
*
* El parámetro nestedProps es un valor entero que indica a que nivel de profundidad se debe navegar a través de las propiedades relacionadas para convertirlas de JPA a TO. Un
* valor 0 indica que no se convertirá ninguna propiedad que tenga un entidad JPA relacionada (tendrá valor null en el objeto TO).
*
* @return VisitTO (Transfer Object del objeto recuperado) o null si el objeto JPA es nulo
*/
public VisitTO getPOJOforVisitJPA(VisitJPA vi, int nestedProps) {
VisitTO qsTO = null;
if (vi != null) {
FamilyDoctorJPA fd = null;
PatientJPA pat = null;
if (nestedProps > 0) {
fd = vi.getFamilyDoctor();
pat = vi.getPatient();
}
nestedProps--;
qsTO = new VisitTO(vi.getId(), vi.getDate(), vi.getTime(), vi.getObservations(), vi.getResult(),
this.getPOJOforFamilyDoctorJPA(fd, nestedProps), this.getPOJOforPatientJPA(pat, nestedProps));
}
return qsTO;
}
public MedicalTestTO getPOJOforMedicalTestJPA(MedicalTestJPA mt, int nestedProps) {
MedicalTestTO qsTO = null;
if (mt != null) {
SpecialistDoctorJPA fd = null;
PatientJPA pat = null;
if (nestedProps > 0) {
fd = mt.getSpecialistDoctor();
pat = mt.getPatient();
}
nestedProps--;
qsTO = new MedicalTestTO(mt.getId(), mt.getDate(), mt.getTime(), mt.getObservations(), mt.getHighresimage(), mt.getType(),
this.getPOJOforPatientJPA(pat, nestedProps), this.getPOJOforSpecialistDoctorJPA(fd, nestedProps));
}
return qsTO;
}
}

View File

@@ -6,16 +6,20 @@ import javax.ejb.Local;
import TO.FamilyDoctorTO;
import TO.MedicalSpecialtyTO;
import TO.MedicalTestTO;
import TO.PatientTO;
import TO.PrimaryHealthCareCenterTO;
import TO.QuestionTO;
import TO.SpecialistDoctorTO;
import TO.VisitTO;
import jpa.FamilyDoctorJPA;
import jpa.MedicalSpecialtyJPA;
import jpa.MedicalTestJPA;
import jpa.PatientJPA;
import jpa.PrimaryHealthCareCenterJPA;
import jpa.QuestionJPA;
import jpa.SpecialistDoctorJPA;
import jpa.VisitJPA;
/**
*
@@ -43,6 +47,10 @@ public interface CommonFacadeLocal {
public List<FamilyDoctorTO> listFamilyDoctorsFiltered(String searchTerm, int pageNumber, int pageSize);
public List<PatientTO> listPatientsPaged(int pageNumber, int pageSize);
public List<PatientTO> listPatientsFiltered(String searchTerm, int pageNumber, int pageSize);
public PatientTO findPatientById(int patientId);
public PatientTO findPatientByCode(String code);
@@ -72,4 +80,8 @@ public interface CommonFacadeLocal {
public PatientTO getPOJOforPatientJPA(PatientJPA pat, int nestedProps);
public QuestionTO getPOJOforQuestionJPA(QuestionJPA qs, int nestedProps);
public MedicalTestTO getPOJOforMedicalTestJPA(MedicalTestJPA mt, int nestedProps);
public VisitTO getPOJOforVisitJPA(VisitJPA qs, int nestedProps);
}

View File

@@ -1,6 +1,5 @@
package ejb.common;
import java.util.Collection;
import java.util.List;
import javax.ejb.Remote;
@@ -10,9 +9,6 @@ import TO.MedicalSpecialtyTO;
import TO.PatientTO;
import TO.PrimaryHealthCareCenterTO;
import TO.SpecialistDoctorTO;
import jpa.FamilyDoctorJPA;
import jpa.PatientJPA;
import jpa.SpecialistDoctorJPA;
/**
*
@@ -40,6 +36,10 @@ public interface CommonFacadeRemote {
public List<FamilyDoctorTO> listFamilyDoctorsFiltered(String searchTerm, int pageNumber, int pageSize);
public List<PatientTO> listPatientsPaged(int pageNumber, int pageSize);
public List<PatientTO> listPatientsFiltered(String searchTerm, int pageNumber, int pageSize);
public PatientTO findPatientById(int patientId);
public PatientTO findPatientByCode(String code);

View File

@@ -1,7 +1,8 @@
package ejb.medicalTest;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
@@ -10,25 +11,24 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import TO.MedicalTestTO.MedicalTestType;
import TO.MedicalTestTO;
import TO.PatientTO;
import TO.QuestionTO;
import TO.SpecialistDoctorTO;
import common.MedicalTestType;
import common.QuestionStatus;
import common.UserType;
import common.Utils;
import ejb.common.CommonFacadeLocal;
import jpa.FamilyDoctorJPA;
import jpa.MedicalTestJPA;
import jpa.PatientJPA;
import jpa.QuestionJPA;
import managedbean.common.SessionUtils;
import jpa.SpecialistDoctorJPA;
/**
* EJB Session Bean Class para la Practica 2, Ejercicio 1 (ISCSD) Implementa los
* métodos de la capa de negocio que implementan la logica de negocio y la
* interacción con la capa de persistencia.
* EJB Session Bean Class para la Practica 2, Ejercicio 1 (ISCSD) Implementa los métodos de la capa de negocio que implementan la logica de negocio y la interacción con la capa de
* persistencia.
*
* Tanto los pacientes como los médicos deben acceder a la vista de pruebas
* médicas.
* Tanto los pacientes como los médicos deben acceder a la vista de pruebas médicas.
*
* @author rorden
*
@@ -52,18 +52,27 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
* @param title
* @param message
*/
@Override
public void askQuestion(int professionalNumber, String title, String message) {
if (SessionUtils.getUserType() == UserType.PATIENT) {
LoggedUserTO user = SessionUtils.getloggedOnUser();
// 0. Conseguir el paciente en sesión
PatientJPA patient = entman.find(PatientJPA.class, user.getId());
// 1. Buscar el médico de familia con ese professionalNumber
FamilyDoctorJPA fdoctor = entman.find(FamilyDoctorJPA.class, professionalNumber);
// 2. Crear un objeto de Question para ese médico desde el paciente en sesión
QuestionJPA question = new QuestionJPA(0, title, message, QuestionStatus.PENDING, patient, fdoctor, null);
// 3. Guardar
entman.persist(question);
public String askQuestion(int userId, String title, String message) {
PatientJPA pat = entman.find(PatientJPA.class, userId);
if (pat.getFamilyDoctor() != null) {
QuestionJPA qjpa = new QuestionJPA();
qjpa.setId(0);
qjpa.setTitle(title);
qjpa.setMessage(message);
qjpa.setStatus(QuestionStatus.PENDING);
qjpa.setPatient(pat);
qjpa.setFamilyDoctor(pat.getFamilyDoctor());
entman.persist(qjpa);
return "ok";
} else {
return "No tienes médico de familia elegido, por favor acude a la sección 'Gestionar Perfil' -> 'Cambiar médico de familia'";
}
}
@@ -73,32 +82,23 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
* @param question
* @param response
*/
@Override
public void answerQuestion(String question, String response) {
public void answerQuestion(int questionId, String response) {
QuestionJPA qjpa;
qjpa = entman.find(QuestionJPA.class, questionId);
qjpa.setResponse(response);
qjpa.setStatus(QuestionStatus.ANSWERED);
entman.persist(qjpa);
}
public List<QuestionTO> listAllPendingQuestions(int familyDoctorId) {
return null;
}
public Long getPendingQuestionsCount(int familyDoctorId) {
TypedQuery<Long> query = entman.createQuery("SELECT count(1) from QuestionJPA q where q.status=:status and q.familyDoctor.id=:docId", Long.class);
query.setParameter("status", QuestionStatus.PENDING);
// TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA
// q where q.status=:status and q.familyDoctor.id=:docId order by q.title",
// QuestionJPA.class);
TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA q where q.familyDoctor.id=:docId order by q.status desc, q.title asc", QuestionJPA.class);
// query.setParameter("status", QuestionStatus.PENDING);
query.setParameter("docId", familyDoctorId);
return query.getSingleResult();
}
public List<QuestionTO> listPendingQuestionsPaged(int familyDoctorId, int pageNumber, int pageSize) {
TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA q where q.status=:status and q.familyDoctor.id=:docId order by q.title", QuestionJPA.class);
query.setParameter("status", QuestionStatus.PENDING);
query.setParameter("docId", familyDoctorId);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<QuestionJPA> allJPA = query.getResultList();
List<QuestionTO> pendingQuestions = new ArrayList<QuestionTO>();
@@ -109,13 +109,39 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
return pendingQuestions;
}
public List<QuestionTO> listAllMyQuestions(int userId) {
List<QuestionTO> pendingQuestions = new ArrayList<QuestionTO>();
// TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA
// q where q.status=:status and q.familyDoctor.id=:docId order by q.title",
// QuestionJPA.class);
TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA q where q.patient.id=:patientId order by q.status desc, q.title asc", QuestionJPA.class);
// query.setParameter("status", QuestionStatus.PENDING);
query.setParameter("patientId", userId);
List<QuestionJPA> allJPA = query.getResultList();
for (QuestionJPA item : allJPA) {
pendingQuestions.add(commonServices.getPOJOforQuestionJPA(item, 1));
}
return pendingQuestions;
}
/**
* Recuperar una pregunta por su String
* Recuperar una pregunta por su identificador
*
* @param question
*/
@Override
public void getQuestion(String question) {
public QuestionTO getQuestion(int idQuestion) {
QuestionTO resp = new QuestionTO();
TypedQuery<QuestionJPA> query = entman.createQuery("SELECT q from QuestionJPA q where q.id=:idquestion", QuestionJPA.class);
query.setParameter("idquestion", idQuestion);
resp = commonServices.getPOJOforQuestionJPA(query.getSingleResult(), 1);
return resp;
}
// *********************************************************************
@@ -124,17 +150,23 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
/**
* Añadir pruebas médicas a una cita
*
* Sólo médicos especialistas pueden gestionar pruebas médicas en el sistema.
* Dado que será añadida por el médico especialista en sesión no hace falta más información.
*
* @param idMedicalTest
* @param patientiID
* @param date
* @param time
* @param testType Pudiera llegar a ser: Análisis de sangre, resonancias
* magnéticas y TAC
* @param testType Pudiera llegar a ser: Análisis de sangre, resonancias magnéticas y TAC
* @param observations
*/
@Override
public void addMedicalTest(int idMedicalTest, Date date, long time, MedicalTestType testType, String observations) {
public MedicalTestTO addMedicalTest(int patientID, int doctorSpecialistID, LocalDate date, LocalTime time, MedicalTestType testType, String observations) throws Exception {
SpecialistDoctorJPA specDoctor = entman.find(SpecialistDoctorJPA.class, doctorSpecialistID);
PatientJPA pat = entman.find(PatientJPA.class, patientID);
MedicalTestJPA mt = new MedicalTestJPA(date, time, observations, null, testType, pat, specDoctor);
entman.persist(mt);
return this.commonServices.getPOJOforMedicalTestJPA(mt, 1);
}
/**
@@ -144,8 +176,18 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
*
* @param idMedicalTest
*/
@Override
public void getMedicalTest(int idMedicalTest) {
public MedicalTestTO getMedicalTest(int idMedicalTest) {
MedicalTestTO resp = new MedicalTestTO();
resp = commonServices.getPOJOforMedicalTestJPA(this.getMedicalTestJPA(idMedicalTest), 1);
return resp;
}
private MedicalTestJPA getMedicalTestJPA(int idMedicalTest) {
TypedQuery<MedicalTestJPA> query = entman.createQuery("SELECT q from MedicalTestJPA q where q.id=:idMedicalTest", MedicalTestJPA.class);
query.setParameter("idMedicalTest", idMedicalTest);
return query.getSingleResult();
}
/**
@@ -154,8 +196,11 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
* @param idMedicalTest
* @param image
*/
@Override
public void addImage(int idMedicalTest, String image) {
MedicalTestJPA mt = this.getMedicalTestJPA(idMedicalTest);
mt.setHighresimage(image);
entman.persist(mt);
}
/**
@@ -164,8 +209,8 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
* @param idMedicalTest
* @param image
*/
@Override
public void updateImage(int idMedicalTest, String image) {
this.addImage(idMedicalTest, image);
}
/**
@@ -173,8 +218,18 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
*
* @param idMedicalTest
*/
@Override
public void removeImage(int idMedicalTest) {
MedicalTestJPA mt = this.getMedicalTestJPA(idMedicalTest);
mt.setHighresimage(null);
entman.persist(mt);
}
public Long getSpecialistDoctorByMedicalSpecialityCount(int specialityId) {
TypedQuery<Long> query = entman.createQuery("SELECT count(1) from SpecialistDoctorJPA q where q.medicalSpecialty.id=:specId", Long.class);
query.setParameter("specId", specialityId);
return query.getSingleResult();
}
/**
@@ -182,8 +237,172 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote {
*
* @param speciality
*/
public List<SpecialistDoctorTO> findSpecialistDoctorByMedicalSpeciality(int specialityId, int pageNumber, int pageSize) {
List<SpecialistDoctorTO> pendingQuestions = new ArrayList<SpecialistDoctorTO>();
TypedQuery<SpecialistDoctorJPA> query = entman.createQuery(
"SELECT q from SpecialistDoctorJPA q where q.medicalSpecialty.id=:specId order by q.medicalSpecialty.name asc, q.surname asc", SpecialistDoctorJPA.class);
query.setParameter("specId", specialityId);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<SpecialistDoctorJPA> allJPA = query.getResultList();
for (SpecialistDoctorJPA item : allJPA) {
pendingQuestions.add(commonServices.getPOJOforSpecialistDoctorJPA(item, 1));
}
return pendingQuestions;
}
@Override
public void findSpecialistDoctorByMedicalSpeciality(MedicalSpecialtyTO speciality) {
public List<MedicalTestTO> loadMedicalTestForPatient(int patientID) {
List<MedicalTestTO> medicalTests = new ArrayList<MedicalTestTO>();
TypedQuery<MedicalTestJPA> query = entman.createQuery("SELECT q from MedicalTestJPA q where q.patient.id=:patientId order by q.id desc", MedicalTestJPA.class);
query.setParameter("patientId", patientID);
List<MedicalTestJPA> allJPA = query.getResultList();
for (MedicalTestJPA item : allJPA) {
medicalTests.add(commonServices.getPOJOforMedicalTestJPA(item, 1));
}
return medicalTests;
}
@Override
public List<MedicalTestTO> loadMedicalTestForFamilyDoctor(int familyDoctorID) {
return this.loadMedicalTestForFamilyDoctor(familyDoctorID, -1);
}
@Override
public List<MedicalTestTO> loadMedicalTestForSpecialistDoctor(int specialistDoctorID) {
return this.loadMedicalTestForSpecialistDoctor(specialistDoctorID, -1);
}
@Override
public List<MedicalTestTO> loadMedicalTestForFamilyDoctor(int familyDoctorID, int patientID) {
List<MedicalTestTO> medicalTests = new ArrayList<MedicalTestTO>();
String extraQuery = "";
if (patientID >= 0) {
extraQuery = " and q.patient.id=:patientID";
}
TypedQuery<MedicalTestJPA> query = entman
.createQuery("SELECT q from MedicalTestJPA q where q.patient.familyDoctor.id=:familyDoctorID " + extraQuery + " order by q.id desc", MedicalTestJPA.class);
if (patientID >= 0) {
query.setParameter("patientID", patientID);
}
query.setParameter("familyDoctorID", familyDoctorID);
List<MedicalTestJPA> allJPA = query.getResultList();
for (MedicalTestJPA item : allJPA) {
medicalTests.add(commonServices.getPOJOforMedicalTestJPA(item, 1));
}
return medicalTests;
}
@Override
public List<MedicalTestTO> loadMedicalTestForSpecialistDoctor(int specialistDoctorID, int patientID) {
List<MedicalTestTO> medicalTests = new ArrayList<MedicalTestTO>();
String extraQuery = "";
if (patientID >= 0) {
extraQuery = " and q.patient.id=:patientID";
}
TypedQuery<MedicalTestJPA> query = entman
.createQuery("SELECT q from MedicalTestJPA q where q.specialistDoctor.id=:specialistDoctorID " + extraQuery + " order by q.id desc", MedicalTestJPA.class);
if (patientID >= 0) {
query.setParameter("patientID", patientID);
}
query.setParameter("specialistDoctorID", specialistDoctorID);
List<MedicalTestJPA> allJPA = query.getResultList();
for (MedicalTestJPA item : allJPA) {
medicalTests.add(commonServices.getPOJOforMedicalTestJPA(item, 1));
}
return medicalTests;
}
public List<PatientTO> loadPatientsForSpecialistDoctor(int specialistDoctorID, String searchTerm, int pageNumber, int pageSize) {
String strQuery = "SELECT distinct q.patient from MedicalTestJPA q where q.specialistDoctor.id=:specialistDoctorID %s order by q.patient.name, q.patient.surname";
String strFilter = "";
if (searchTerm == null)
searchTerm = "";
else
searchTerm = Utils.normalizeTerm(searchTerm);
if (searchTerm.length() > 0) {
strFilter = "and (lower(q.patient.name) LIKE :searchTerm OR lower(q.patient.surname) LIKE :searchTerm)";
}
TypedQuery<PatientJPA> query = entman.createQuery(String.format(strQuery, strFilter), PatientJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
query.setParameter("specialistDoctorID", specialistDoctorID);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<PatientJPA> allJPA = query.getResultList();
List<PatientTO> patsTO = new ArrayList<PatientTO>();
for (PatientJPA item : allJPA) {
patsTO.add(commonServices.getPOJOforPatientJPA(item, 1));
}
return patsTO;
}
public List<PatientTO> loadPatientsForFamilyDoctor(int familyDoctorID, String searchTerm, int pageNumber, int pageSize) {
String strQuery = "SELECT distinct q.patient from MedicalTestJPA q where q.patient.familyDoctor.id=:familyDoctorID %s order by q.patient.name, q.patient.surname";
String strFilter = "";
if (searchTerm == null)
searchTerm = "";
else
searchTerm = Utils.normalizeTerm(searchTerm);
if (searchTerm.length() > 0) {
strFilter = "and (lower(q.patient.name) LIKE :searchTerm OR lower(q.patient.surname) LIKE :searchTerm)";
}
TypedQuery<PatientJPA> query = entman.createQuery(String.format(strQuery, strFilter), PatientJPA.class);
if (searchTerm.length() > 0)
query.setParameter("searchTerm", "%" + searchTerm + "%");
query.setParameter("familyDoctorID", familyDoctorID);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<PatientJPA> allJPA = query.getResultList();
List<PatientTO> patsTO = new ArrayList<PatientTO>();
for (PatientJPA item : allJPA) {
patsTO.add(commonServices.getPOJOforPatientJPA(item, 1));
}
return patsTO;
}
}

View File

@@ -1,17 +1,19 @@
package ejb.medicalTest;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import javax.ejb.Remote;
import TO.MedicalSpecialtyTO;
import TO.MedicalTestTO.MedicalTestType;
import TO.MedicalTestTO;
import TO.PatientTO;
import TO.QuestionTO;
import TO.SpecialistDoctorTO;
import common.MedicalTestType;
/**
* Interfaz remota del EJB Definimos los métodos que estarán disponibles para
* los clientes del EJB
* Interfaz remota del EJB Definimos los métodos que estarán disponibles para los clientes del EJB
*
* @author rorden
*
@@ -25,19 +27,22 @@ public interface MedicalTestFacadeRemote {
/**
* Realizar una pregunta al médico por un paciente
*
* @param professionalNumber
* @param userID Este parámetro en el enunciado era del doctor, se ha cambiado al del paciente ya que los EJB
* no tienen el contexto de la sesión y de esta forma se puede conseguir el médico al que se realiza la
* pregunta.
* @param title
* @param message
*/
public void askQuestion(int professionalNumber, String title, String message);
public String askQuestion(int userID, String title, String message);
/**
* El médico responde a una pregunta
*
* @param question
* @param questionId Se ha cambiado a questionID ya que es más directa la identificación de la pregunta
* a la que se va a responder
* @param response
*/
public void answerQuestion(String question, String response);
public void answerQuestion(int questionId, String response);
/**
* Recuperar las preguntas sin respuesta para un médico
@@ -48,38 +53,55 @@ public interface MedicalTestFacadeRemote {
*/
public List<QuestionTO> listAllPendingQuestions(int familyDoctorId);
public Long getPendingQuestionsCount(int familyDoctorId);
public List<QuestionTO> listPendingQuestionsPaged(int familyDoctorId, int pageNumber, int pageSize);
/**
* Recuperar las preguntas hechas por un paciente
*
* NEW
*/
public List<QuestionTO> listAllMyQuestions(int userId);
/**
* Recuperar una pregunta por su String
*
* @param question
* @param idQuestion Se ha cambiado al identificador de la pregunta, ya que es más directa
* su identificación.
*/
public void getQuestion(String question);
public QuestionTO getQuestion(int idQuestion);
// ********************************************************************* MEDICAL
// TEST
public List<MedicalTestTO> loadMedicalTestForPatient(int patientID);
public List<MedicalTestTO> loadMedicalTestForFamilyDoctor(int familyDoctorID);
public List<MedicalTestTO> loadMedicalTestForSpecialistDoctor(int specialistDoctorID);
public List<MedicalTestTO> loadMedicalTestForFamilyDoctor(int familyDoctorID, int patientID);
public List<MedicalTestTO> loadMedicalTestForSpecialistDoctor(int specialistDoctorID, int patientID);
public List<PatientTO> loadPatientsForSpecialistDoctor(int specialistDoctorID, String searchTerm, int pageNumber, int pageSize);
public List<PatientTO> loadPatientsForFamilyDoctor(int familyDoctorID, String searchTerm, int pageNumber, int pageSize);
/**
* Añadir una prueba médica a un paciente
* Añadir una prueba médica a un paciente Dado que será añadida por el médico especialista en sesión no hace falta más información.
*
* @param idMedicalTest
* @param date
* @param time
* @param testType Pudiera llegar a ser: Análisis de sangre, resonancias
* magnéticas y TAC
* @param testType Pudiera llegar a ser: Análisis de sangre, resonancias magnéticas y TAC
* @param observations
*/
public void addMedicalTest(int id, Date date, long time, MedicalTestType testType, String observations);
public MedicalTestTO addMedicalTest(int patientID, int doctorSpecialistID, LocalDate date, LocalTime time, MedicalTestType testType, String observations) throws Exception;
/**
* Recuperar una prueba médica por ID
*
* @param idMedicalTest
*/
public void getMedicalTest(int idPatient);
public MedicalTestTO getMedicalTest(int idPatient);
/**
* Añadir una imagen a una prueba médica
@@ -104,10 +126,12 @@ public interface MedicalTestFacadeRemote {
*/
public void removeImage(int idMedicalTest);
public Long getSpecialistDoctorByMedicalSpecialityCount(int specialityId);
/**
* Listar médicos con una especialidad concreta
*
* @param speciality
*/
public void findSpecialistDoctorByMedicalSpeciality(MedicalSpecialtyTO speciality);
public List<SpecialistDoctorTO> findSpecialistDoctorByMedicalSpeciality(int specialityId, int pageNumber, int pageSize);
}

View File

@@ -278,8 +278,6 @@ public class ProfileFacadeBean implements ProfileFacadeRemote {
* @return FamilyDoctorTO (Transfer Object del médico de familia al que se la ha cambiado el CAP).
*/
public FamilyDoctorTO changePrimaryHealthCareCenter(int professionalId, PrimaryHealthCareCenterTO newCenter) throws Exception {
FamilyDoctorTO fdTO = null;
FamilyDoctorJPA fd = entman.find(FamilyDoctorJPA.class, professionalId);
if (fd == null) {
throw new Exception("No se encuentra en la base de datos ningún médico de familia con id: " + String.valueOf(professionalId));

View File

@@ -1,21 +1,28 @@
package ejb.systemAdmin;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import TO.FamilyDoctorTO;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import TO.PatientTO;
import TO.PrimaryHealthCareCenterTO;
import TO.SpecialistDoctorTO;
import common.Constants;
import common.HashUtils;
import common.UserType;
import ejb.common.CommonFacadeLocal;
import jpa.AdministratorJPA;
import jpa.FamilyDoctorJPA;
import jpa.MedicalSpecialtyJPA;
import jpa.PrimaryHealthCareCenterJPA;
/**
*
@@ -33,29 +40,23 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
CommonFacadeLocal commonServices;
/**
* Si la autenticación no es correcgta devuelve null, sino devuelve un POJO con
* datos del usuario logeado.
* Si la autenticación no es correcgta devuelve null, sino devuelve un POJO con datos del usuario logeado.
*
* La autenticación se realiza en 2 pasos:
*
* Paso 1. Se intenta localizar un registro de usuario, por orden:
*
* a. Primero Paciente, si el identificador comienza por los caracteres
* correctos.
* a. Primero Paciente, si el identificador comienza por los caracteres correctos.
*
* b.Después médico de familia, si el identificador es de profesional
*
* c. Si no lo localizamos buscamos el identificador en la tabla de médicos
* especialistas (el identificador es de profesional)
* c. Si no lo localizamos buscamos el identificador en la tabla de médicos especialistas (el identificador es de profesional)
*
* d. Si no hemos localizado aún al usuario, lo buscamos en la tabla de
* administradores, aún cuando el identificador comience por cualquier carácter
* (podría ser una dirección de email que comienza por caracteres del
* identificaodr de paciente o profesional)
* d. Si no hemos localizado aún al usuario, lo buscamos en la tabla de administradores, aún cuando el identificador comience por cualquier carácter (podría ser una dirección
* de email que comienza por caracteres del identificaodr de paciente o profesional)
*
* Paso 2. Si hemos localizado un registro de usuario, verificamos si el
* password recibido coincide con el de la base de datos, en tal caso la
* autenticación se compelta y es correcta.
* Paso 2. Si hemos localizado un registro de usuario, verificamos si el password recibido coincide con el de la base de datos, en tal caso la autenticación se compelta y es
* correcta.
*/
public LoggedUserTO login(String userCode, String pwd) {
LoggedUserTO usr = null;
@@ -65,7 +66,7 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
// login.
PatientTO pat = this.commonServices.findPatientByCode(userCode);
if (pat != null) {
usr = new LoggedUserTO(String.valueOf(pat.getId()), pat.getName(), pat.getPassword(), UserType.PATIENT);
usr = new LoggedUserTO(String.valueOf(pat.getId()), pat.getName(), pat.getPassword(), UserType.PATIENT, pat.getDisplayName());
}
} else if (userCode.startsWith(Constants.PROFESSIONAL_NUMBER_PREFIX)) {
// Si el identificador de usuario es de tipo profesional, intentamos realizar el
@@ -73,13 +74,13 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
FamilyDoctorTO fd = this.commonServices.findFamilyDoctorByCode(userCode);
if (fd != null) {
usr = new LoggedUserTO(String.valueOf(fd.getId()), fd.getName(), fd.getPassword(), UserType.FAMILY_DOCTOR);
usr = new LoggedUserTO(String.valueOf(fd.getId()), fd.getName(), fd.getPassword(), UserType.FAMILY_DOCTOR, fd.getDisplayName());
} else {
// No era un código de médico de familia, intenamos logearlo como especialista
SpecialistDoctorTO sd = this.commonServices.findSpecialistDoctorByCode(userCode);
if (sd != null) {
usr = new LoggedUserTO(String.valueOf(sd.getId()), sd.getName(), sd.getPassword(), UserType.SPECIALIST_DOCTOR);
usr = new LoggedUserTO(String.valueOf(sd.getId()), sd.getName(), sd.getPassword(), UserType.SPECIALIST_DOCTOR, sd.getDisplayName());
}
}
}
@@ -93,7 +94,7 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
AdministratorJPA adm = entman.find(AdministratorJPA.class, userCode);
if (adm != null) {
usr = new LoggedUserTO(adm.getEmail(), adm.getEmail(), adm.getPassword(), UserType.ADMINISTRATOR);
usr = new LoggedUserTO(adm.getEmail(), adm.getEmail(), adm.getPassword(), UserType.ADMINISTRATOR, adm.getEmail());
}
}
@@ -111,7 +112,7 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
}
@Override
public MedicalSpecialtyTO updateSpecialtyData(int id, String name, String description) throws Exception {
public MedicalSpecialtyTO updateSpecialty(int id, String name, String description) throws Exception {
MedicalSpecialtyJPA ms = entman.find(MedicalSpecialtyJPA.class, id);
if (ms == null) {
@@ -126,8 +127,20 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
return this.commonServices.getPOJOforMedicalSpecialtyJPA(ms);
}
public MedicalSpecialtyTO findSpecialtyByName(String searchedName) {
TypedQuery<MedicalSpecialtyJPA> query = entman.createQuery("from MedicalSpecialtyJPA ms where ms.name=:name", MedicalSpecialtyJPA.class);
query.setMaxResults(1);
query.setParameter("name", searchedName);
List<MedicalSpecialtyJPA> results = query.getResultList();
if (results.size() > 0)
return this.commonServices.getPOJOforMedicalSpecialtyJPA(results.get(0));
else
return null;
}
@Override
public void deleteSpecialtyData(int id, String name, String description) throws Exception {
public void deleteSpecialty(int id) throws Exception {
MedicalSpecialtyJPA ms = entman.find(MedicalSpecialtyJPA.class, id);
if (ms == null) {
@@ -138,11 +151,109 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
}
@Override
public MedicalSpecialtyTO insertSpecialtyData(String name, String description) throws Exception {
public MedicalSpecialtyTO insertSpecialty(String name, String description) throws Exception {
MedicalSpecialtyJPA ms = new MedicalSpecialtyJPA(name, description);
entman.persist(ms);
return this.commonServices.getPOJOforMedicalSpecialtyJPA(ms);
}
@Override
public PrimaryHealthCareCenterTO updateHealthCareCenter(int id, String name, String location) throws Exception {
PrimaryHealthCareCenterJPA ms = entman.find(PrimaryHealthCareCenterJPA.class, id);
if (ms == null) {
throw new Exception("No se pueden actualizar los datos del CAP porque no se encuentra en la base de datos ningún registro con id: " + String.valueOf(id));
}
ms.setName(name);
ms.setLocation(location);
entman.persist(ms);
return this.commonServices.getPOJOforPrimaryHealthCareCenterJPA(ms);
}
public PrimaryHealthCareCenterTO findHealthCareCenterByName(String searchedName) {
TypedQuery<PrimaryHealthCareCenterJPA> query = entman.createQuery("from PrimaryHealthCareCenterJPA cap where cap.name=:name", PrimaryHealthCareCenterJPA.class);
query.setMaxResults(1);
query.setParameter("name", searchedName);
List<PrimaryHealthCareCenterJPA> results = query.getResultList();
if (results.size() > 0)
return this.commonServices.getPOJOforPrimaryHealthCareCenterJPA(results.get(0));
else
return null;
}
@Override
public void deleteHealthCareCenter(int id) throws Exception {
PrimaryHealthCareCenterJPA cap = entman.find(PrimaryHealthCareCenterJPA.class, id);
if (cap == null) {
throw new Exception("No se puede borrar el CAP porque no se encuentra en la base de datos ningún registro con id: " + String.valueOf(id));
}
entman.remove(cap);
}
@Override
public PrimaryHealthCareCenterTO insertHealthCareCenter(String name, String location) throws Exception {
PrimaryHealthCareCenterJPA cap = new PrimaryHealthCareCenterJPA(name, location);
entman.persist(cap);
return this.commonServices.getPOJOforPrimaryHealthCareCenterJPA(cap);
}
public Long getCAPCount() {
TypedQuery<Long> query = entman.createQuery("SELECT count(1) from PrimaryHealthCareCenterJPA", Long.class);
return query.getSingleResult();
}
public List<PrimaryHealthCareCenterTO> listCAPsPaged(int pageNumber, int pageSize) {
TypedQuery<PrimaryHealthCareCenterJPA> query = entman.createQuery("SELECT c from PrimaryHealthCareCenterJPA c order by c.name", PrimaryHealthCareCenterJPA.class);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<PrimaryHealthCareCenterJPA> allJPA = query.getResultList();
List<PrimaryHealthCareCenterTO> caps = new ArrayList<PrimaryHealthCareCenterTO>();
for (PrimaryHealthCareCenterJPA item : allJPA) {
caps.add(commonServices.getPOJOforPrimaryHealthCareCenterJPA(item));
}
return caps;
}
public List<FamilyDoctorTO> listAllFamilyDoctorsByCAPPaged(int primaryHealthCareCenterId, int pageNumber, int pageSize) {
List<FamilyDoctorTO> familyDoctorsByCAP = new ArrayList<FamilyDoctorTO>();
TypedQuery<FamilyDoctorJPA> query = entman.createQuery("SELECT d from FamilyDoctorJPA d where d.primaryHealthCareCenter.id=:capId order by d.name asc, d.surname asc",
FamilyDoctorJPA.class);
query.setParameter("capId", primaryHealthCareCenterId);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<FamilyDoctorJPA> allJPA = query.getResultList();
for (FamilyDoctorJPA item : allJPA) {
familyDoctorsByCAP.add(commonServices.getPOJOforFamilyDoctorJPA(item, 1));
}
return familyDoctorsByCAP;
}
public Long getPatientCount(int familyDoctorId) {
TypedQuery<Long> query = entman.createQuery("SELECT count(1) from PatientJPA p where p.familyDoctor.id=:familyDoctorId", Long.class);
query.setParameter("familyDoctorId", familyDoctorId);
return query.getSingleResult();
}
}

View File

@@ -1,9 +1,13 @@
package ejb.systemAdmin;
import java.util.List;
import javax.ejb.Remote;
import TO.FamilyDoctorTO;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import TO.PrimaryHealthCareCenterTO;
/**
*
@@ -18,9 +22,27 @@ public interface SystemAdminFacadeRemote {
public LoggedUserTO login(String id, String pwd);
public MedicalSpecialtyTO updateSpecialtyData(int id, String name, String description) throws Exception;
public MedicalSpecialtyTO updateSpecialty(int id, String name, String description) throws Exception;
public void deleteSpecialtyData(int id, String name, String description) throws Exception;
public MedicalSpecialtyTO findSpecialtyByName(String name);
public MedicalSpecialtyTO insertSpecialtyData(String name, String description) throws Exception;
public void deleteSpecialty(int id) throws Exception;
public MedicalSpecialtyTO insertSpecialty(String name, String description) throws Exception;
public PrimaryHealthCareCenterTO updateHealthCareCenter(int id, String name, String location) throws Exception;
public PrimaryHealthCareCenterTO findHealthCareCenterByName(String name);
public void deleteHealthCareCenter(int id) throws Exception;
public PrimaryHealthCareCenterTO insertHealthCareCenter(String name, String location) throws Exception;
public Long getCAPCount();
public List<PrimaryHealthCareCenterTO> listCAPsPaged(int pageNumber, int pageSize);
public List<FamilyDoctorTO> listAllFamilyDoctorsByCAPPaged(int primaryHealthCareCenterId, int pageNumber, int pageSize);
public Long getPatientCount(int familyDoctorId);
}

View File

@@ -1,28 +1,158 @@
package ejb.visit;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import TO.VisitTO;
import ejb.common.CommonFacadeLocal;
import jpa.PatientJPA;
import jpa.VisitJPA;
/**
* EJB Session Bean Class para la Practica 2, Ejercicio 1 (ISCSD) Implementa los
* métodos de la capa de negocio que implementan la logica de negocio y la
* interacción con la capa de persistencia.
* EJB Session Bean Class para la Practica 2, Ejercicio 1 (ISCSD) Implementa los métodos de la capa de negocio que implementan la logica de negocio y la interacción con la capa de
* persistencia.
*
* @author mark
*
*/
@Stateless
public class VisitFacadeBean implements VisitFacadeRemote {
// Persistence Unit Context
@PersistenceContext(unitName = "MyHealth")
private EntityManager entman;
EntityManager entman;
public void ejbMethod(String parameter)
{
@EJB
CommonFacadeLocal commonServices;
public Long getScheduledVisitsCount(int familyDoctorId, LocalDate date) {
TypedQuery<Long> query = entman.createQuery("SELECT count(1) from VisitJPA v where v.date=:date and v.familyDoctor.id=:docId", Long.class);
query.setParameter("date", date);
query.setParameter("docId", familyDoctorId);
return query.getSingleResult();
}
public List<VisitTO> listAllScheduledVisitsPaged(int familyDoctorId, LocalDate date, int pageNumber, int pageSize) {
TypedQuery<VisitJPA> query = entman.createQuery("SELECT v from VisitJPA v where v.date=:date and v.familyDoctor.id=:docId order by v.date, v.time", VisitJPA.class);
query.setParameter("date", date);
query.setParameter("docId", familyDoctorId);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<VisitJPA> allJPA = query.getResultList();
List<VisitTO> listTO = new ArrayList<VisitTO>();
for (VisitJPA item : allJPA) {
listTO.add(commonServices.getPOJOforVisitJPA(item, 1));
}
return listTO;
}
public Long getVisitsCount(Integer patientId, LocalDate date) {
String strQuery = "SELECT count(1) from VisitJPA v %s";
String strFilter = "";
if (patientId != null)
strFilter = " and v.patient.id=:patientId ";
if (date != null)
strFilter += " and v.date=:date ";
if (strFilter.length() > 0) {
strFilter = "WHERE 1=1 " + strFilter;
}
strQuery = String.format(strQuery, strFilter);
TypedQuery<Long> query = entman.createQuery(strQuery, Long.class);
if (patientId != null)
query.setParameter("patientId", patientId);
if (date != null)
query.setParameter("date", date);
return query.getSingleResult();
}
public List<VisitTO> listVisitsPaged(Integer patientId, LocalDate date, int pageNumber, int pageSize) {
String strQuery = "SELECT v from VisitJPA v %s order by v.patient, v.date";
String strFilter = "";
if (patientId != null)
strFilter = " and v.patient.id=:patientId ";
if (date != null)
strFilter += " and v.date=:date ";
if (strFilter.length() > 0) {
strFilter = "WHERE 1=1 " + strFilter;
}
strQuery = String.format(strQuery, strFilter);
TypedQuery<VisitJPA> query = entman.createQuery(strQuery, VisitJPA.class);
if (patientId != null)
query.setParameter("patientId", patientId);
if (date != null)
query.setParameter("date", date);
if (pageSize > 0) {
query.setFirstResult(pageNumber * pageSize);
query.setMaxResults(pageSize);
}
List<VisitJPA> allJPA = query.getResultList();
List<VisitTO> listTO = new ArrayList<VisitTO>();
for (VisitJPA item : allJPA) {
listTO.add(commonServices.getPOJOforVisitJPA(item, 1));
}
return listTO;
}
public VisitTO getVisit(int id) throws Exception {
VisitJPA vi = entman.find(VisitJPA.class, id);
if (vi == null) {
throw new Exception("No se encuentra la visita con identificador: " + String.valueOf(id));
}
return this.commonServices.getPOJOforVisitJPA(vi, 1);
}
public void addResultToVisit(int id, String result) {
VisitJPA vi = entman.find(VisitJPA.class, id);
vi.setResult(result);
entman.persist(vi);
}
public void removeVisit(int id) {
VisitJPA vi = entman.find(VisitJPA.class, id);
entman.remove(vi);
}
public void updateVisit(int id, LocalDate date, LocalTime time) {
VisitJPA vi = entman.find(VisitJPA.class, id);
vi.setDate(date);
vi.setTime(time);
entman.persist(vi);
}
public VisitTO addVisit(int patientId, LocalDate date, LocalTime time, String observations) {
PatientJPA pat = entman.find(PatientJPA.class, patientId);
VisitJPA vi = new VisitJPA(date, time, observations, "", pat, pat.getFamilyDoctor());
entman.persist(vi);
return this.commonServices.getPOJOforVisitJPA(vi, 1);
}
}

View File

@@ -1,12 +1,17 @@
package ejb.visit;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import javax.ejb.Remote;
import TO.VisitTO;
/**
* Interfaz remota del EJB Definimos los métodos que estarán disponibles para
* los clientes del EJB
* Interfaz remota del EJB Definimos los métodos que estarán disponibles para los clientes del EJB
*
* @author mark
* @author alina
*
*/
@Remote
@@ -14,5 +19,23 @@ public interface VisitFacadeRemote {
/**
* Definimos la interfaz remota
*/
public void ejbMethod(String parameter);
public Long getScheduledVisitsCount(int familyDoctorId, LocalDate date);
public List<VisitTO> listAllScheduledVisitsPaged(int familyDoctorId, LocalDate date, int pageNumber, int pageSize);
public Long getVisitsCount(Integer patientId, LocalDate date);
public List<VisitTO> listVisitsPaged(Integer patientId, LocalDate date, int pageNumber, int pageSize);
public VisitTO getVisit(int id) throws Exception;
public void addResultToVisit(int id, String result);
public void removeVisit(int id);
public void updateVisit(int id, LocalDate date, LocalTime time);
public VisitTO addVisit(int patientId, LocalDate date, LocalTime time, String observations);
}

View File

@@ -1,7 +1,8 @@
package jpa;
import java.io.Serializable;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalTime;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -14,7 +15,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import common.TestType;
import common.MedicalTestType;
/**
* Los nombres de los decortadores relacionados con la BBDD pueden estar en
@@ -35,14 +36,14 @@ public class MedicalTestJPA implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private Date date;
private long time;
private LocalDate date;
private LocalTime time;
private String observations;
private String highresimage;
@Enumerated(EnumType.STRING)
@Column(name = "type") // Con esto podríamos cambiar los nombres de las propiedades de la clase y
// mantener la relación con la BBDD a través de JPA
private TestType type;
private MedicalTestType type;
@ManyToOne
@JoinColumn(name = "patientid")
@@ -56,8 +57,7 @@ public class MedicalTestJPA implements Serializable {
super();
}
public MedicalTestJPA(int id, Date date, long time, String observations, String highresimage, TestType type, PatientJPA patient, SpecialistDoctorJPA specialistDoctor) {
this.id = id;
public MedicalTestJPA(LocalDate date, LocalTime time, String observations, String highresimage, MedicalTestType type, PatientJPA patient, SpecialistDoctorJPA specialistDoctor) {
this.date = date;
this.time = time;
this.observations = observations;
@@ -75,19 +75,19 @@ public class MedicalTestJPA implements Serializable {
this.id = id;
}
public Date getDate() {
public LocalDate getDate() {
return date;
}
public void setDate(Date date) {
public void setDate(LocalDate date) {
this.date = date;
}
public long getTime() {
public LocalTime getTime() {
return time;
}
public void setTime(long time) {
public void setTime(LocalTime time) {
this.time = time;
}
@@ -107,11 +107,11 @@ public class MedicalTestJPA implements Serializable {
this.highresimage = highresimage;
}
public TestType getType() {
public MedicalTestType getType() {
return type;
}
public void setType(TestType type) {
public void setType(MedicalTestType type) {
this.type = type;
}

View File

@@ -1,8 +1,8 @@
package jpa;
import java.io.Serializable;
import java.sql.Time;
import java.util.Date;
import java.time.LocalDate;
import java.time.LocalTime;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -28,13 +28,15 @@ public class VisitJPA implements Serializable {
@Column(updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Date date;
private Time time;
private LocalDate date;
private LocalTime time;
private String observations;
private String result;
@ManyToOne
@JoinColumn(name = "FamilyDoctorId")
private FamilyDoctorJPA familyDoctor;
@ManyToOne
@JoinColumn(name = "PatientId")
private PatientJPA patient;
@@ -46,16 +48,15 @@ public class VisitJPA implements Serializable {
super();
}
public VisitJPA(Integer id, Date date, Time time, String observations, String result) {
this.id = id;
public VisitJPA(LocalDate date, LocalTime time, String observations, String result, PatientJPA patient, FamilyDoctorJPA familydoctor) {
this.date = date;
this.time = time;
this.observations = observations;
this.result = result;
this.patient = patient;
this.familyDoctor = familydoctor;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
@@ -64,19 +65,19 @@ public class VisitJPA implements Serializable {
this.id = value;
}
public Date getDate() {
public LocalDate getDate() {
return date;
}
public void setDate(Date value) {
public void setDate(LocalDate value) {
this.date = value;
}
public Time getTime() {
public LocalTime getTime() {
return time;
}
public void setTime(Time value) {
public void setTime(LocalTime value) {
this.time = value;
}
@@ -84,8 +85,8 @@ public class VisitJPA implements Serializable {
return observations;
}
public void setObservations(String observation) {
this.observations = observations;
public void setObservations(String value) {
this.observations = value;
}
/**
@@ -106,4 +107,12 @@ public class VisitJPA implements Serializable {
public void setPatient(PatientJPA pat) {
this.patient = pat;
}
public String getResult() {
return result;
}
public void setResult(String value) {
this.result = value;
}
}

View File

@@ -20,6 +20,7 @@ import org.omnifaces.util.Exceptions;
import common.UserType;
import common.Utils;
import managedbean.systemAdmin.LoginMBean;
@WebFilter(filterName = "AuthFilter", urlPatterns = { "*.xhtml" })
public class AuthorizationFilter implements Filter {
@@ -46,12 +47,35 @@ public class AuthorizationFilter implements Filter {
HttpServletRequest req = null;
HttpServletResponse resp = null;
HttpSession ses = null;
// Si establecemos esta variable a true se realiza el autologin
// TODO: Eliminar esta variable al terminar el desarrollo
boolean Debug = false;
try {
req = (HttpServletRequest) request;
String reqURI = req.getRequestURI();
resp = (HttpServletResponse) response;
// TODO: Eliminar este código al terminar el desarrollo.
// Realizamos un login automatico (para agilizar el desarrollo.
if (Debug == true) {
ses = req.getSession(true);
if (SessionUtils.isLogedIn(ses) == false) {
LoginMBean login = new LoginMBean();
login.setUsername("PRO#100");
login.setPassword("asdf");
boolean result = login.autoLogin(ses);
if (result == true)
SessionUtils.addMessage(ses, FacesMessage.SEVERITY_ERROR, "Login automático correcto", "Se ha realizado un login automático correctamente.");
else
SessionUtils.addMessage(ses, FacesMessage.SEVERITY_ERROR, "El login automático ha fallado.", "No se ha podido realizar el login automático.");
}
}
ses = req.getSession(false);
// Para recursos publicos permitimos el acceso exista sesión o no.
@@ -85,7 +109,7 @@ public class AuthorizationFilter implements Filter {
authorized = true;
if (reqURI.indexOf("/systemAdmin/ListDoctorsByCenter") > 0)
authorized = true;
if (reqURI.indexOf("/visit/VisitView") > 0)
if (reqURI.indexOf("/visit/PatientVisitList") > 0)
authorized = true;
if (reqURI.indexOf("/visit/UpdateVisit") > 0)
authorized = true;
@@ -97,15 +121,15 @@ public class AuthorizationFilter implements Filter {
authorized = true;
if (reqURI.indexOf("/visit/UpdateVisit") > 0)
authorized = true;
if (reqURI.indexOf("/visit/CancelVisit") > 0)
if (reqURI.indexOf("/visit/PatientVisitList") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/AddQuestion") > 0)
if (reqURI.indexOf("/medicaltest/Questions") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/ViewMedicalTest") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/MedicalTests") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/SearchSpecialistBySpecialty") > 0)
if (reqURI.indexOf("/medicaltest/SearchSpecialist") > 0)
authorized = true;
if (reqURI.indexOf("/profile/UpdateProfile") > 0)
authorized = true;
@@ -115,15 +139,13 @@ public class AuthorizationFilter implements Filter {
case FAMILY_DOCTOR:
if (reqURI.indexOf("/visit/VisitView") > 0)
authorized = true;
if (reqURI.indexOf("/visit/VisitAddResult") > 0)
if (reqURI.indexOf("/visit/UpdateVisit") > 0)
authorized = true;
if (reqURI.indexOf("/visit/VisitViewSchedules") > 0)
if (reqURI.indexOf("/visit/VisitList") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/MedicalTests") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/AnswerQuestion") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/PendingQuestions") > 0)
if (reqURI.indexOf("/medicaltest/Questions") > 0)
authorized = true;
if (reqURI.indexOf("/medicaltest/ViewMedicalTest") > 0)
authorized = true;
@@ -159,17 +181,19 @@ public class AuthorizationFilter implements Filter {
}
resp.sendRedirect(req.getContextPath() + "/home.xhtml");
resp.sendRedirect(req.getContextPath() + "/login.xhtml");
} catch (Exception e) {
if (Exceptions.is(e, PersistenceException.class) == true) {
if (ses != null)
SessionUtils.addMessage(ses, FacesMessage.SEVERITY_ERROR, "Error al intentar acceder a la base de datos", Utils.getExceptionRootCause(e).getLocalizedMessage());
resp.sendRedirect(req.getContextPath() + "/error.xhtml?type=sql");
} else
} else {
SessionUtils.addMessage(ses, FacesMessage.SEVERITY_ERROR, "Error interno del servidor", Utils.getExceptionRootCause(e).getLocalizedMessage());
resp.sendRedirect(req.getContextPath() + "/error.xhtml");
}
}
}
@Override
public void destroy() {

View File

@@ -127,14 +127,13 @@ public class ManagedBeanBase {
String strType = "";
if (ex.getClass().equals(ViewExpiredException.class)) {
// Sessión expired
// Sessión expirada
strType = "expired";
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Su sesión ha caducado", "Su sesión ha caducado, vuelva a logarse en el sistema.");
} else {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Se ha producido un error inesperado", "Descripción del error: " + ex.getLocalizedMessage());
this.addFacesMessageKeep(FacesMessage.SEVERITY_ERROR, "Se ha producido un error inesperado", "Descripción del error: " + ex.getLocalizedMessage());
}
try {
ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();

View File

@@ -4,8 +4,6 @@ import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.primefaces.model.menu.DefaultMenuItem;
@@ -41,12 +39,12 @@ public class MenuMBean implements Serializable {
// Administracion Sistema
if (tipoUsuario == UserType.ADMINISTRATOR) {
subMenu = new DefaultSubMenu("Administración del sistema", "fa-wrench");
subMenu = new DefaultSubMenu("Administración del sistema", "fa fa-wrench");
subMenu.addElement(createMenuItem("Gestionar especialidades", "fa fa-file-text-o", "/systemAdmin/ManageSpecialties", null));
subMenu.addElement(createMenuItem("Centros At. Primaria", "fa fa-hospital-o", "/systemAdmin/ManageSpecialties", null));
subMenu.addElement(createMenuItem("Centros At. Primaria", "fa fa-hospital-o", "/systemAdmin/ManageHealthCareCenters", null));
subMenu.addElement(new DefaultSeparator());
subMenu.addElement(createMenuItem("Ver médicos de un CAP", "fa fa-medkit", "/systemAdmin/ManageSpecialties", null));
subMenu.addElement(createMenuItem("Ver médicos de un CAP", "fa fa-medkit", "/systemAdmin/ListDoctorsByCenter", null));
subMenu.addElement(new DefaultSeparator());
subMenu.addElement(createMenuItem("Añadir usuario Admin", "fa fa-user-secret", "/systemAdmin/ManageSpecialties", null));
@@ -58,15 +56,15 @@ public class MenuMBean implements Serializable {
subMenu = new DefaultSubMenu("Visitas", "fa fa-calendar");
if (tipoUsuario == UserType.PATIENT)
subMenu.addElement(createMenuItem("Solicitar nueva", "fa fa-calendar-o", "/visit/VisitView", null));
subMenu.addElement(createMenuItem("Solicitar nueva", "fa fa-calendar-o", "/visit/AddVisit", null));
if (tipoUsuario == UserType.PATIENT || tipoUsuario == UserType.ADMINISTRATOR)
subMenu.addElement(createMenuItem("Modificar fecha/hora", "fa fa-briefcase", "/visit/VisitView", null));
subMenu.addElement(createMenuItem("Modificar fecha/hora", "fa fa-briefcase", "/visit/PatientVisitList", null));
if (tipoUsuario == UserType.PATIENT)
subMenu.addElement(createMenuItem("Anular visita", "fa fa-remove", "/visit/VisitView", null));
subMenu.addElement(createMenuItem("Anular visita", "fa fa-remove", "/visit/PatientVisitList", null));
if (tipoUsuario == UserType.FAMILY_DOCTOR)
subMenu.addElement(createMenuItem("Añadir resultado", "fa fa-align-left", "/visit/VisitView", null));
subMenu.addElement(createMenuItem("Añadir resultado", "fa fa-align-left", "/visit/VisitList", null));
if (tipoUsuario == UserType.FAMILY_DOCTOR)
subMenu.addElement(createMenuItem("Ver agenda del día", "fa fa-repeat", "/visit/VisitView", null));
subMenu.addElement(createMenuItem("Ver agenda del día", "fa fa-repeat", "/visit/VisitList", null));
model.addElement(subMenu);
}
@@ -88,25 +86,14 @@ public class MenuMBean implements Serializable {
}
if (tipoUsuario == UserType.PATIENT)
subMenu.addElement(createMenuItem("Buscar especialista...", "fa fa-heartbeat", "/medicaltest/MedicalTests", null));
subMenu.addElement(createMenuItem("Buscar especialista...", "fa fa-heartbeat", "/medicaltest/SearchSpecialist", null));
model.addElement(subMenu);
}
// Preguntas médicas
if (tipoUsuario == UserType.PATIENT || tipoUsuario == UserType.FAMILY_DOCTOR) {
subMenu = new DefaultSubMenu("Preguntas", "fa fa-question-circle");
if (tipoUsuario == UserType.PATIENT)
subMenu.addElement(createMenuItem("Hacer pregunta", "fa fa-comment-o", "/medicaltest/MedicalTests", null));
if (tipoUsuario == UserType.FAMILY_DOCTOR)
subMenu.addElement(createMenuItem("Responder pregunta", "fa fa-comments", "/medicaltest/MedicalTests", null));
if (tipoUsuario == UserType.FAMILY_DOCTOR)
subMenu.addElement(createMenuItem("Ver preguntas pendientes", "fa fa-comments-o", "/medicaltest/PendingQuestions", null));
model.addElement(subMenu);
model.addElement(createMenuItem("Preguntas", "fa fa-comment-o", "/medicaltest/Questions", null));
}
}

View File

@@ -17,14 +17,18 @@ public class SessionUtils {
public static final String SESSION_VAR_USER = "loggedOnUser";
public static final String SESSION_VAR_MESSAGE = "facesMessage";
public static HttpSession getSession() {
public static HttpSession getSession(boolean create) {
FacesContext ctx = FacesContext.getCurrentInstance();
if (ctx != null)
return (HttpSession) ctx.getExternalContext().getSession(false);
return (HttpSession) ctx.getExternalContext().getSession(create);
else
return null;
}
public static HttpSession getSession() {
return getSession(false);
}
public static HttpServletRequest getRequest() {
return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
}
@@ -33,8 +37,14 @@ public class SessionUtils {
return ((HttpServletRequest) request).getSession(false);
}
public static void CreateSession(LoggedUserTO usr) {
HttpSession ses = getSession();
public static void createOrUpdateSession(LoggedUserTO usr) {
createOrUpdateSession(getSession(true), usr);
}
public static void createOrUpdateSession(HttpSession ses, LoggedUserTO usr) {
if (ses == null)
return;
ses.setAttribute(SessionUtils.SESSION_VAR_USERNAME, usr.getName());
ses.setAttribute(SessionUtils.SESSION_VAR_USERID, usr.getId());
ses.setAttribute(SessionUtils.SESSION_VAR_USERTYPE, usr.getUserType());
@@ -73,6 +83,16 @@ public class SessionUtils {
return "";
}
public static String getUserDisplayName() {
HttpSession session = getSession();
if (session != null && session.getAttribute(SessionUtils.SESSION_VAR_USER) != null) {
LoggedUserTO usr = LoggedUserTO.class.cast(session.getAttribute(SessionUtils.SESSION_VAR_USER));
return usr.getDisplayName();
} else
return "";
}
public static UserType getUserType() {
return getUserType(getSession());
}

View File

@@ -1,16 +1,16 @@
package managedbean.common;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class ThemeService {
/**
*
*/
public class ThemeService implements Serializable {
private static final long serialVersionUID = 1L;
public static final String DEFAULT_THEME = "nova-light";
public static final List<Theme> THEMES = new ArrayList<Theme>() {
private static final long serialVersionUID = 1L;
{
int i = 1;
add(new Theme(i++, "afterdark", "afterdark"));

View File

@@ -15,6 +15,9 @@ public class ValidationUtils {
static final String NIF_LETTERS = "TRWAGMYFPDXBNJZSQVHLCKE";
static final String NIE_LETTERS = "XYZ";
public static String normalizeNIF(String nif) {
return nif.toUpperCase().replace("-", "").replace(".", "");
}
/**
*
* @param nif NIF a validar
@@ -24,7 +27,7 @@ public class ValidationUtils {
if (nif == null)
return false;
nif = nif.toUpperCase().replace("-", "").replace(".", "");
nif = normalizeNIF(nif);
if (nif.length() < 2 || nif.length() > 9)
return false;
@@ -85,9 +88,9 @@ public class ValidationUtils {
// para los especialistas
SpecialistDoctorTO sd = remoteSvc.findSpecialistDoctorByNif(nif);
if (sd != null && (id == null || sd.getId() != id))
if (sd != null && (id == null || sd.getId().equals(id) == false))
nifExists = true;
} else if (id == null || fd.getId() != id)
} else if (id == null || fd.getId().equals(id) == false )
// Si se trata de un usuario diferente, entonces está repetido
nifExists = true;
@@ -96,7 +99,7 @@ public class ValidationUtils {
PatientTO pat = remoteSvc.findPatientByNif(nif);
// Si se trata de un usuario diferente, entonces está repetido
if (pat != null && (id == null || pat.getId() != id))
if (pat != null && (id == null || pat.getId().equals(id) == false))
nifExists = true;
break;
}

View File

@@ -4,8 +4,8 @@ import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import common.UserType;
@@ -16,22 +16,23 @@ import common.UserType;
*
*/
@Named("home")
@RequestScoped
@ViewScoped
public class homeMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private boolean isLogedIn;
private String userId;
private String userName;
private String userDisplayName;
private UserType userType;
private int refresh;
@PostConstruct
public void init() {
isLogedIn = SessionUtils.isLogedIn();
userName = SessionUtils.getUserName();
userId = SessionUtils.getUserId();
userType = SessionUtils.getUserType();
this.isLogedIn = SessionUtils.isLogedIn();
this.userName = SessionUtils.getUserName();
this.userDisplayName = SessionUtils.getUserDisplayName();
this.userId = SessionUtils.getUserId();
this.userType = SessionUtils.getUserType();
FacesMessage message = SessionUtils.getMessage();
@@ -55,6 +56,13 @@ public class homeMBean extends ManagedBeanBase implements Serializable {
return this.userName;
}
public String getUserDisplayName() {
if (this.isLogedIn == false)
return "Invitado";
else
return this.userDisplayName;
}
public String getUserId() {
return this.userId;
}
@@ -63,14 +71,6 @@ public class homeMBean extends ManagedBeanBase implements Serializable {
return this.userType.getUserTypename();
}
public int getRefresh() {
return refresh;
}
public void setRefresh(int refresh) {
this.refresh = refresh;
}
public boolean isPatient() {
return (this.userType == UserType.PATIENT);
}

View File

@@ -1,27 +1,322 @@
package managedbean.medicalTest;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import managedbean.common.ManagedBeanBase;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.UploadedFile;
@Named("MedicalTestMBean")
@RequestScoped
import TO.MedicalTestTO;
import TO.PatientTO;
import common.Constants;
import common.MedicalTestType;
import common.UserType;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("mt")
@ViewScoped
public class MedicalTestMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private int userID;
private UserType userType;
private List<MedicalTestTO> medicalTests;
private MedicalTestTO selected;
private PatientTO patSelected;
private PatientTO patientFilterSelected;
private boolean addNewMode = false;
private UploadedFile imageUpload;
private List<PatientTO> patientList;
private List<PatientTO> patientWithTestList;
private String lastUIQuery;
private String lastUIQueryPatFilter;
private List<MedicalTestType> medicalTestTypes;
private LocalDate testDate;
private LocalTime testTime;
private String testObservations;
private MedicalTestType testType;
public MedicalTestMBean() {
}
@PostConstruct
public void init() {
// Inicialización de variables y propiedades van aquí.
this.userType = SessionUtils.getUserType();
this.userID = Integer.valueOf(SessionUtils.getUserId());
// Como realizar llamadas al EJB Remoto
// this.getRemoteManagerSystemAdmin().MetodoEJB
this.medicalTestTypes = new ArrayList<MedicalTestType>();
this.medicalTestTypes.add(MedicalTestType.BLOOD_TEST);
this.medicalTestTypes.add(MedicalTestType.CT_SCAN);
this.medicalTestTypes.add(MedicalTestType.MAGNETIC_RESONANCE_IMAGING);
this.selected = null;
this.patSelected = null;
this.lastUIQuery = "";
this.lastUIQueryPatFilter = "";
switch (userType) {
case ADMINISTRATOR:
case PATIENT:
this.patientList = null;
this.patientWithTestList = null;
break;
case SPECIALIST_DOCTOR:
this.patientList = this.getRemoteManagerCommon().listPatientsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
this.patientWithTestList = this.getRemoteManagerMedicalTest().loadPatientsForSpecialistDoctor(userID, null, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
break;
case FAMILY_DOCTOR:
this.patientList = null;
this.patientWithTestList = this.getRemoteManagerMedicalTest().loadPatientsForFamilyDoctor(userID, null, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
this.loadMedicalTests();
}
public void addImage() {
if (this.imageUpload != null) {
String content = "data:" + imageUpload.getContentType() + ";base64," + Base64.getEncoder().encodeToString(imageUpload.getContents());
System.out.println("FILE Content base64: ");
System.out.println(content);
this.selected.setHighresimage(content);
getRemoteManagerMedicalTest().addImage(this.selected.getId(), content);
this.loadMedicalTests();
this.imageUpload = null;
} else {
System.out.println("IMAGEN SUBIDA ES NULA");
}
}
public UploadedFile getImageUpload() {
return imageUpload;
}
public void setImageUpload(UploadedFile imageUpload) {
this.imageUpload = imageUpload;
}
public void removeImage() {
this.selected.setHighresimage(null);
getRemoteManagerMedicalTest().removeImage(this.selected.getId());
this.loadMedicalTests();
}
public MedicalTestTO getSelected() {
return this.selected;
}
public void setSelected(MedicalTestTO selected) {
this.selected = selected;
}
public PatientTO getPatSelected() {
return this.patSelected;
}
public void setPatSelected(PatientTO s) {
this.patSelected = s;
}
public void loadMedicalTests() {
Integer patId = -1;
if (this.patientFilterSelected != null)
patId = this.patientFilterSelected.getId();
switch (userType) {
case PATIENT:
// Cargar las pruebas para el paciente en sesión
this.medicalTests = getRemoteManagerMedicalTest().loadMedicalTestForPatient(userID);
break;
case SPECIALIST_DOCTOR:
// Cargar las pruebas que el doctor especialista ha creado
this.medicalTests = getRemoteManagerMedicalTest().loadMedicalTestForSpecialistDoctor(userID, patId);
break;
case FAMILY_DOCTOR:
// Cargar las pruebas para los pacientes del doctor de familia en sesión
this.medicalTests = getRemoteManagerMedicalTest().loadMedicalTestForFamilyDoctor(userID, patId);
break;
case ADMINISTRATOR:
this.medicalTests = null;
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Operación no válida para el tipo de usuario actual.");
break;
}
}
public List<PatientTO> completePatient(String query) {
if (query != null && query.equals(this.lastUIQuery) == false) {
this.lastUIQuery = query;
// Recuperamos las xxx primeras coincidencias
this.patientList = this.getRemoteManagerCommon().listPatientsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.patientList;
}
public List<PatientTO> completePatientFilter(String query) {
if (query != null && query.equals(this.lastUIQueryPatFilter) == false) {
this.lastUIQueryPatFilter = query;
switch (userType) {
case SPECIALIST_DOCTOR:
// Cargar los pacientes a los que ha añadido pruebas médicas el médico especialista
this.patientWithTestList = this.getRemoteManagerMedicalTest().loadPatientsForSpecialistDoctor(userID, query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
break;
case FAMILY_DOCTOR:
// Cargar los pacientes del médico de familia que tiene pruebas médicas hechas
this.patientWithTestList = this.getRemoteManagerMedicalTest().loadPatientsForFamilyDoctor(userID, query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
break;
case ADMINISTRATOR:
case PATIENT:
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Operación no válida para el tipo de usuario actual.");
this.patientWithTestList = null;
break;
}
}
return this.patientWithTestList;
}
public List<PatientTO> getPatientList() {
return patientList;
}
public List<PatientTO> getPatientWithTestList() {
return patientWithTestList;
}
public List<MedicalTestTO> getMedicalTests() {
return this.medicalTests;
}
public void setMedicalTests(List<MedicalTestTO> list) {
// Nothing to do
}
public boolean isSpecialistDoctor() {
return this.userType == UserType.SPECIALIST_DOCTOR;
}
public boolean isPatSelector() {
return !(userType == UserType.PATIENT);
}
public void clearFilteredPatient() {
this.addNewMode = false;
this.selected = null;
this.patientFilterSelected = null;
this.loadMedicalTests();
}
public void onChangePatient(AjaxBehaviorEvent event) {
this.selected = null;
this.loadMedicalTests();
}
public void onSelectPatient(SelectEvent event) {
this.selected = null;
this.patientFilterSelected = (PatientTO) event.getObject();
this.loadMedicalTests();
}
public void onSelectMT(SelectEvent event) {
this.selected = (MedicalTestTO) event.getObject();
this.addNewMode = false;
}
public void addMT() {
// Si hay un paciente filtrado en la busqueda de pruebas, lo seleccionamos para la prueba a añadir.
//this.patSelected = this.patientFilterSelected;
this.testDate = LocalDate.now();
this.testTime = LocalTime.now();
this.testObservations = "";
this.testType = MedicalTestType.BLOOD_TEST;
this.addNewMode = true;
}
public boolean isAddNewMode() {
return addNewMode;
}
public void setAddNewMode(boolean addNewMode) {
this.addNewMode = addNewMode;
}
public boolean getViewCreate() {
return addNewMode && userType == UserType.SPECIALIST_DOCTOR;
}
public boolean getViewEdit() {
return !addNewMode && this.selected != null;
}
public List<MedicalTestType> getMedicalTestTypes() {
return this.medicalTestTypes;
}
public void save() {
try {
MedicalTestTO mt = this.getRemoteManagerMedicalTest().addMedicalTest(this.patSelected.getId(), this.userID, this.testDate, this.testTime, this.testType,
this.testObservations);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Éxito", String.format("La prueba médica se ha guardado correctamente, el identificador asignado es: %d", mt.getId()));
// Volvemos al modo añadir (limpiamos el formulario).
this.addMT();
this.loadMedicalTests();
} catch (Exception ex) {
this.manageException(ex);
}
}
public PatientTO getPatientFilterSelected() {
return patientFilterSelected;
}
public void setPatientFilterSelected(PatientTO patientFilterSelected) {
this.patientFilterSelected = patientFilterSelected;
}
public LocalDate getTestDate() {
return testDate;
}
public void setTestDate(LocalDate testDate) {
this.testDate = testDate;
}
public LocalTime getTestTime() {
return testTime;
}
public void setTestTime(LocalTime testTime) {
this.testTime = testTime;
}
public String getTestObservations() {
return testObservations;
}
public void setTestObservations(String testObservations) {
this.testObservations = testObservations;
}
public MedicalTestType getTestType() {
return testType;
}
public void setTestType(MedicalTestType testType) {
this.testType = testType;
}
}

View File

@@ -1,53 +0,0 @@
package managedbean.medicalTest;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.QuestionTO;
import common.Constants;
import ejb.medicalTest.MedicalTestFacadeRemote;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("PendingQuestions")
@ViewScoped
public class PendingQuestionsMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private int familyDoctorId;
private LazyDataModel<QuestionTO> lazyDataModelQuestionList;
public PendingQuestionsMBean() {
}
@PostConstruct
public void init() {
// Inicialización de variables y propiedades van aquí.
this.familyDoctorId = Integer.valueOf(SessionUtils.getUserId());
this.lazyDataModelQuestionList = new LazyDataModel<QuestionTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<QuestionTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
Long totalRowCount = getRemoteManagerMedicalTest().getPendingQuestionsCount(familyDoctorId);
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerMedicalTest().listPendingQuestionsPaged(familyDoctorId, (first / pageSize), pageSize);
}
};
}
public LazyDataModel<QuestionTO> getLazyDataModelQuestionList() {
return lazyDataModelQuestionList;
}
}

View File

@@ -0,0 +1,137 @@
package managedbean.medicalTest;
import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.event.SelectEvent;
import TO.QuestionTO;
import common.QuestionStatus;
import common.UserType;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("Questions")
@ViewScoped
public class QuestionsMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private int userID;
private UserType userType;
private List<QuestionTO> pendingQuestions;
private QuestionTO selected;
private boolean addNewMode;
public QuestionsMBean() {
}
@PostConstruct
public void init() {
// Inicialización de variables y propiedades van aquí.
this.userType = SessionUtils.getUserType();
this.userID = Integer.valueOf(SessionUtils.getUserId());
this.addNewMode = false;
this.selected = null;
this.loadQuestions();
}
public List<QuestionTO> getPendingQuestions() {
return pendingQuestions;
}
public void setPendingQuestions(List<QuestionTO> value) {
this.pendingQuestions = value;
}
/**
* Cargará las preguntas enviadas al médico o escritas por el paciente, esto irá en función del tipo de usuario en sesión
*/
private void loadQuestions() {
if (this.userType == UserType.FAMILY_DOCTOR) {
// Listar las preguntas destinadas a él
// El método disponible del API básico es referente al doctor
this.pendingQuestions = getRemoteManagerMedicalTest().listAllPendingQuestions(userID);
} else if (this.userType == UserType.PATIENT) {
// Listar las preguntas realiadas por él
// Para reutilizar la misma view, necesitaremos nuevos métodos para el API de
// cara a recoger sus preguntas realizadas.
this.pendingQuestions = getRemoteManagerMedicalTest().listAllMyQuestions(userID);
}
}
public void onSelect(SelectEvent event) {
this.addNewMode = false;
this.selected = (QuestionTO) event.getObject();
}
public void onUnSelect(SelectEvent event) {
this.selected = null;
}
public void setSelected(QuestionTO selected) {
this.selected = selected;
}
public QuestionTO getSelected() {
return this.selected;
}
public void save() {
getRemoteManagerMedicalTest().answerQuestion(this.selected.getId(), this.selected.getResponse());
this.loadQuestions();
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Datos guardados", "La respuesta se registrado correctamente en el sistema.");
this.selected = null;
}
public void create() {
this.addNewMode = true;
this.selected = new QuestionTO();
this.selected.setId(-1);
this.selected.setTitle("");
this.selected.setMessage("");
}
public void addNewQuestion() {
String result = getRemoteManagerMedicalTest().askQuestion(userID, this.selected.getTitle(), this.selected.getMessage());
if(result == "ok") {
this.create();
this.loadQuestions();
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Datos guardados", "La pregunta se registrado correctamente en el sistema.");
} else {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Error", result);
}
}
public boolean isShowPanelDetail() {
return this.selected != null && this.addNewMode == false;
}
public boolean isPatient() {
return (this.userType == UserType.PATIENT);
}
public boolean isFamilyDoctor() {
return (this.userType == UserType.FAMILY_DOCTOR);
}
public boolean isAddNewMode() {
return addNewMode;
}
public boolean isRespuestaEditable() {
return (this.userType == UserType.FAMILY_DOCTOR && this.selected != null && this.selected.getStatus() == QuestionStatus.PENDING);
}
public void setAddNewMode(boolean addNewMode) {
this.addNewMode = addNewMode;
}
}

View File

@@ -0,0 +1,91 @@
package managedbean.medicalTest;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.MedicalSpecialtyTO;
import TO.SpecialistDoctorTO;
import common.Constants;
import managedbean.common.ManagedBeanBase;
@Named("sspec")
@ViewScoped
public class SearchSpecialistMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private List<MedicalSpecialtyTO> medicalSpecialitiesList;
private MedicalSpecialtyTO medicalSpeciality;
private String lastUIQueryMS;
private LazyDataModel<SpecialistDoctorTO> lazyDataModelDoctorList;
public SearchSpecialistMBean() {
}
@PostConstruct
public void init() {
// Inicialización de variables y propiedades van aquí.
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
this.medicalSpeciality = null;
this.lastUIQueryMS = "";
this.lazyDataModelDoctorList = new LazyDataModel<SpecialistDoctorTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<SpecialistDoctorTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
if (medicalSpeciality == null) {
this.setRowCount(0);
return null;
} else {
Long totalRowCount = getRemoteManagerMedicalTest().getSpecialistDoctorByMedicalSpecialityCount(medicalSpeciality.getId());
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerMedicalTest().findSpecialistDoctorByMedicalSpeciality(medicalSpeciality.getId(), (first / pageSize), pageSize);
}
}
};
}
public LazyDataModel<SpecialistDoctorTO> getLazyDataModelDoctorList() {
return lazyDataModelDoctorList;
}
public void showData() {
}
public List<MedicalSpecialtyTO> completeMedicalSpeciality(String query) {
if (query != null && query.equals(this.lastUIQueryMS) == false) {
this.lastUIQueryMS = query;
// Recuperamos las 200 primeras coincidencias
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.medicalSpecialitiesList;
}
public List<MedicalSpecialtyTO> getMedicalSpecialitiesList() {
return medicalSpecialitiesList;
}
public void setMedicalSpecialitiesList(List<MedicalSpecialtyTO> medicalSpecialitiesList) {
this.medicalSpecialitiesList = medicalSpecialitiesList;
}
public MedicalSpecialtyTO getMedicalSpeciality() {
return medicalSpeciality;
}
public void setMedicalSpeciality(MedicalSpecialtyTO medicalSpecialty) {
this.medicalSpeciality = medicalSpecialty;
}
}

View File

@@ -17,6 +17,7 @@ import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
/***
* ManageBean que gestiona la vista para el cambio de médico de familia para un paciente
*
* @author Marcos García Núñez (mgarcianun@uoc.edu)
*
@@ -36,6 +37,14 @@ public class ChangeFamilyDoctorMBean extends ManagedBeanBase implements Serializ
}
/**
* Inicializa el managed Bean
*
* Si el usuario logeado es nulo devuelve un error indicando que la sesión actual no es válida.
*
* Recupera el id del usuario actual desde la sesión. Dado que solo los pacientes pueden seleccionar un médico de familia, si el usuario es de otro tipo se muestra un mensaje
* de error.
*/
@PostConstruct
public void init() {
// Recuperamos el usuario logeado actual
@@ -54,8 +63,9 @@ public class ChangeFamilyDoctorMBean extends ManagedBeanBase implements Serializ
this.familyDoctorList = this.getRemoteManagerCommon().listFamilyDoctorsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
PatientTO pat = this.getRemoteManagerCommon().findPatientById(this.id);
this.setCurrentFamilyDoctor(pat.getFamilyDoctor());
}
this.currentFamilyDoctor = pat.getFamilyDoctor();
} else
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Perfil no válido", "Su tipo de usuario no permite que pueda tener acceso a esta página.");
}
} catch (Exception e) {
this.manageException(e);
@@ -63,33 +73,58 @@ public class ChangeFamilyDoctorMBean extends ManagedBeanBase implements Serializ
}
/**
* Devuelve la lista de médicos de familia para el combo de selección.
*
* @return Lista de médicos de familia.
*/
public List<FamilyDoctorTO> getFamilyDoctorList() {
return familyDoctorList;
}
/**
* Método que permite relizar búsqueda de tipo "typeAhead" en la lista de selección de médico.
*
* Recibe como parámetro el testo tecleado por el usuario
*
* @param query Texto tecleado por el usuario
* @return Retorna la lista de médicos de familia coincidentes con el termino buscado.
*/
public List<FamilyDoctorTO> completeFamilyDoctor(String query) {
if (query != null && query.equals(this.lastUIQuery) == false) {
this.lastUIQuery = query;
// Recuperamos las 200 primeras coincidencias
// Recuperamos las primeras ~30 coincidencias, según constante
this.familyDoctorList = this.getRemoteManagerCommon().listFamilyDoctorsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.familyDoctorList;
}
// Id del usuario actual, obtenido de la sessión del usuario logeado.
public int getId() {
return id;
}
/**
* Método que realiza la persistencia del cambio de médico de familia. a través de la invocación al método EJB correspondiente.
*
* Se realizan 2 comprobaciones adicionales:
*
* 1. Se ha seleccionado un nuevo médico de familia
*
* 2. El médico de familia nuevo es diferente al actual
*
*/
public void saveData() {
int error = 0;
if (this.getNewFamilyDoctor() == null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Nuevo médico de familia no seleccionado", "Por favor, especifique un nuevvo médico de familia.");
this.addFacesMessage("frmChangeFD:newFamilyDocAC", FacesMessage.SEVERITY_WARN, "Nuevo médico de familia no seleccionado",
"Por favor, especifique un nuevvo médico de familia.");
error++;
}
if (this.getCurrentFamilyDoctor() != null && this.getNewFamilyDoctor().getId() == this.getCurrentFamilyDoctor().getId()) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "El médico de familia debe ser diferente",
this.addFacesMessage("frmChangeFD:newFamilyDocAC", FacesMessage.SEVERITY_WARN, "El médico de familia debe ser diferente",
"Por favor, seleccione un médico de familia diferente al que tiene actualmente asignado.");
error++;
}

View File

@@ -1,7 +1,6 @@
package managedbean.profile;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.annotation.PostConstruct;
@@ -18,6 +17,7 @@ import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
/***
* ManagedBean que gestiona la vista para el cambio del centro de atención primaria para los médicos de familia
*
* @author Marcos García Núñez (mgarcianun@uoc.edu)
*
@@ -37,6 +37,12 @@ public class ChangePrimaryHealthCareCenterMBean extends ManagedBeanBase implemen
}
/**
* Inicializa el managed Bean.
*
* Si el usuario atual no se puede recupear de la sesión o si no es un perfil de tipo médicos de familia se muestra un mensaje de error.
*
*/
@PostConstruct
public void init() {
// Recuperamos el usuario logeado actual
@@ -53,11 +59,13 @@ public class ChangePrimaryHealthCareCenterMBean extends ManagedBeanBase implemen
this.id = Integer.valueOf(usr.getId());
if (usr.getUserType() == UserType.FAMILY_DOCTOR) {
// Recupera la lista de CAPs inicial desde el EJB.
this.primaryHealthCareCentersList = this.getRemoteManagerCommon().listCAPsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
FamilyDoctorTO fd = this.getRemoteManagerCommon().findFamilyDoctorById(this.id);
this.setCurrentCenter(fd.getPrimaryHealthCareCenter());
}
} else
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Perfil no válido", "Su tipo de usuario no permite que pueda tener acceso a esta página.");
}
} catch (Exception e) {
this.manageException(e);
@@ -69,6 +77,12 @@ public class ChangePrimaryHealthCareCenterMBean extends ManagedBeanBase implemen
return primaryHealthCareCentersList;
}
/**
* Método que implementa la búsqueda de un CAP a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de CAPs que coinciden con el termino búscado por el usuario.
*/
public List<PrimaryHealthCareCenterTO> completePrimaryHealCareCenter(String query) {
if (query != null && query.equals(this.lastUIQuery) == false) {
this.lastUIQuery = query;
@@ -82,16 +96,24 @@ public class ChangePrimaryHealthCareCenterMBean extends ManagedBeanBase implemen
return id;
}
/**
* Método que realiza el guardado de los cambios a través de la invocación del método del EJB correspondiente.
*
* El método realiza dos verificaciones previas: Que se haya seleccionado un CAP y que este sea diferente del asignado actualmente.
*
*/
public void saveData() {
int error = 0;
if (this.getNewCenter() == null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado", "Por favor, especifique un nuevvo centro de atención primaria.");
this.addFacesMessage("frmChangePHCC:newCenter", FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado",
"Por favor, especifique un nuevvo centro de atención primaria.");
error++;
}
if (this.getNewCenter().getName().equals(this.getCurrentCenter().getName())) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "El centro de atención primeria debe ser diferente", "Por favor, seleccione un centro de atención primaria diferente al cual está actualmente asignado.");
this.addFacesMessage("frmChangePHCC:newCenter", FacesMessage.SEVERITY_WARN, "El centro de atención primeria debe ser diferente",
"Por favor, seleccione un centro de atención primaria diferente al cual está actualmente asignado.");
error++;
}

View File

@@ -24,8 +24,7 @@ import managedbean.common.ManagedBeanBase;
import managedbean.common.ValidationUtils;
/**
* ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente"
* Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista"
* ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente" Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista"
*
* @author Marcos García Núñez (mgarcianun@uoc.edu)
*
@@ -59,6 +58,11 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
}
/**
* Inicializa el managedBean actual.
*
* Carga los tipos de usuario disponibles. Carga la lista de CAPs. Carga la lista de especialidades médicas.
*/
@PostConstruct
public void init() {
this.availableUserTypes = new ArrayList<UserType>();
@@ -79,10 +83,17 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
return availableUserTypes;
}
/**
* Gestiona el evento de cambio de tipo de usuario. El usuario que está intentando registrarse en el sistema ha cambiado el tipo de perfil (usuario) con el cual desea
* registrarse.
*
*/
public void onUserTypeChange() {
switch (this.userType) {
case SPECIALIST_DOCTOR:
try {
// El usuario queire registrarse como médico especialista, lanzamos un evento AJAX de cliente para que la interfaz refleje el cambio en el tipo de usuario
// seleccionado: Se muestra la lista de especialidades médicas para obligar a seleccionar una.
PrimeFaces.current().ajax().addCallbackParam("specs", true);
} catch (Exception e) {
this.manageException(e);
@@ -90,6 +101,8 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
break;
case FAMILY_DOCTOR:
try {
// El usuario queire registrarse como médico especialista, lanzamos un evento AJAX de cliente para que la interfaz refleje el cambio en el tipo de usuario
// seleccionado: Se muestra la lista de CAPs para obligar a seleccionar uno.
PrimeFaces.current().ajax().addCallbackParam("caps", true);
} catch (Exception e) {
this.manageException(e);
@@ -97,6 +110,8 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
break;
case ADMINISTRATOR:
case PATIENT:
// El usuario queire registrarse como médico especialista, lanzamos un evento AJAX de cliente para que la interfaz refleje el cambio en el tipo de usuario
// seleccionado: Se ocultará la lista de selección de CAP o Especialidad médica
PrimeFaces.current().ajax().addCallbackParam("pats", true);
break;
}
@@ -110,6 +125,12 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
return primaryHealthCareCentersList;
}
/**
* Método que implementa la búsqueda de un CAP a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de CAPs que coinciden con el termino búscado por el usuario.
*/
public List<PrimaryHealthCareCenterTO> completePrimaryHealCareCenter(String query) {
if (query != null && query.equals(this.lastUIQueryPH) == false) {
this.lastUIQueryPH = query;
@@ -119,6 +140,12 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
return this.primaryHealthCareCentersList;
}
/**
* Método que implementa la búsqueda de una especialidad a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de especialidades que coinciden con el termino búscado por el usuario.
*/
public List<MedicalSpecialtyTO> completeMedicalSpecialty(String query) {
if (query != null && query.equals(this.lastUIQueryMS) == false) {
this.lastUIQueryMS = query;
@@ -128,14 +155,23 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
return this.medicalSpecialitiesList;
}
public void hadleNIFValueChange() {
/**
* Gestióna el evento de modficación del NIF del usuario actual. Búsca si el NIF ya está en uso para otro usuario. Solo se permite que el mismo NIF se refistro como paciente y
* como médico (especialista o de familia, pero no como ambos).
*
* Un Médico puede estar registrado como paciente con el mismo NIF, pero como médico de familia y especialista al mismo tiempo.
*/
public void handleNIFValueChange() {
boolean isDupe = false;
this.nif = ValidationUtils.normalizeNIF(this.nif);
if (ValidationUtils.checkIfNifAlreadyRegistered(this.getRemoteManagerCommon(), this.userType, this.nif, null) == true) {
isDupe = true;
this.addFacesMessage("frmRegisterUser:nif", FacesMessage.SEVERITY_WARN, "NIF duplicado", "El nif indicado pertenece a otro usuario previamente registrado");
}
PrimeFaces.current().ajax().addCallbackParam("NIFisDupe", isDupe);
PrimeFaces.current().ajax().addCallbackParam("formattedNIF", this.nif);
}
public boolean isPatient() {
@@ -194,15 +230,33 @@ public class RegisterUserMBean extends ManagedBeanBase implements Serializable {
this.nif = nif;
}
/**
* Método que realiza la persistencia de los datos en la base de datos a través de la invocación de los métodos del EJB correspondiente.
*
* Se realizan comprobaciones adicionales para asegurar que:
*
* Si el tipo de usuario que se está registrando es un méidco de familia, obliga a seleccionar un CAP para el usuario.
*
* Si el tipo de usuario que está registrando es un médico especialista, obliga a seleccionar una especialidad médica al usuario.
*
* Si el tipo de usuario que está registrando es un paciente, no obliga a seleccionar un médicos de familia (puede ser nulo) será necesario que el usuario lo seleccione a
* posteriori, una vez logeado en el sistema, a través de la opción de menú correspondiente.
*
* No se permite el registro de administradores a través de la página de registro pública.
*
*/
public void addNewUser() {
int error = 0;
this.nif = ValidationUtils.normalizeNIF(this.nif);
if (this.isFamilyDoctor() && this.primaryHealthCareCenter == null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado", "Por favor, especifique un centro de atención primaria.");
this.addFacesMessage("frmRegisterUser:selPHC", FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado",
"Por favor, especifique un centro de atención primaria.");
error++;
}
if (this.isSpecialistDoctor() && this.medicalSpecialty == null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Especialidad médica no seleccionada", "Por favor, especifique una especialidad médica.");
this.addFacesMessage("frmRegisterUser:selMS", FacesMessage.SEVERITY_WARN, "Especialidad médica no seleccionada", "Por favor, especifique una especialidad médica.");
error++;
}
if (ValidationUtils.isValid(nif) == false) {

View File

@@ -26,8 +26,7 @@ import managedbean.common.SessionUtils;
import managedbean.common.ValidationUtils;
/**
* ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente"
* Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista"
* ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente" Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista"
*
* @author Marcos García Núñez (mgarcianun@uoc.edu)
*
@@ -64,6 +63,12 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
}
/**
* Inicializa el Bean:
*
* Carga la lsita de tipos de usuario (perfiles) Recupera los datos del usuario logeado actualmente, y los asigna a las propiedades del managedBean.
*
*/
@PostConstruct
public void init() {
this.userTypes = new ArrayList<UserType>();
@@ -101,6 +106,7 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
case ADMINISTRATOR:
// TODO: Recuperar usuario administrador para editar su perfil ¿?
// this.getRemoteManagerProfile().retrievePatient(usr.getId());
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario sin perfil", "Usted es un usuario de tipo administrador y no puede editar su perfil de usuario.");
break;
}
}
@@ -109,6 +115,11 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
}
}
/**
* Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un paciente
*
* @param pat Paciente que está editando su perfil, y cuyos datos deben mostrarse en la vista.
*/
private void setPatientData(PatientTO pat) {
this.id = pat.getId();
this.cipCode = pat.getPersonalIdentificationCode();
@@ -120,6 +131,11 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
this.familyDoctor = pat.getFamilyDoctor();
}
/**
* Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un médico de familia
*
* @param fd FamilyDoctor que está editando su perfil, y cuyos datos deben mostrarse en la vista.
*/
private void setFamilyDoctorData(FamilyDoctorTO fd) {
this.id = fd.getId();
this.cipCode = fd.getProfessionalNumber();
@@ -131,6 +147,11 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
this.primaryHealthCareCenter = fd.getPrimaryHealthCareCenter();
}
/**
* Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un médico especialista
*
* @param sd SpecialistDoctor que está editando su perfil, y cuyos datos deben mostrarse en la vista.
*/
private void setSpecialistDoctorData(SpecialistDoctorTO sd) {
this.id = sd.getId();
this.cipCode = sd.getProfessionalNumber();
@@ -154,38 +175,65 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
return primaryHealthCareCentersList;
}
/**
* Método que implementa la búsqueda de un CAP a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de CAPs que coinciden con el termino búscado por el usuario.
*/
public List<PrimaryHealthCareCenterTO> completePrimaryHealCareCenter(String query) {
if (query != null && query.equals(this.lastUIQueryPH) == false) {
this.lastUIQueryPH = query;
// Recuperamos las 200 primeras coincidencias
// Recuperamos las XXX primeras coincidencias
this.primaryHealthCareCentersList = this.getRemoteManagerCommon().listCAPsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.primaryHealthCareCentersList;
}
/**
* Método que implementa la búsqueda de una especialidad a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de especialidades que coinciden con el termino búscado por el usuario.
*/
public List<MedicalSpecialtyTO> completeMedicalSpecialty(String query) {
if (query != null && query.equals(this.lastUIQueryMS) == false) {
this.lastUIQueryMS = query;
// Recuperamos las 200 primeras coincidencias
// Recuperamos las XXX primeras coincidencias
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.medicalSpecialitiesList;
}
public void hadleNIFValueChange() {
/**
* Gestióna el evento de modficación del NIF del usuario actual. Búsca si el NIF ya está en uso para otro usuario. Solo se permite que el mismo NIF se refistro como paciente y
* como médico (especialista o de familia, pero no como ambos).
*
* Un Médico puede estar registrado como paciente con el mismo NIF, pero como médico de familia y especialista al mismo tiempo.
*/
public void handleNIFValueChange() {
boolean isDupe = false;
this.nif = ValidationUtils.normalizeNIF(this.nif);
if (ValidationUtils.checkIfNifAlreadyRegistered(this.getRemoteManagerCommon(), this.userType, this.nif, this.id) == true) {
isDupe = true;
this.addFacesMessage("frmUpdateProfile:nif", FacesMessage.SEVERITY_WARN, "NIF duplicado", "El nif indicado pertenece a otro usuario previamente registrado");
}
PrimeFaces.current().ajax().addCallbackParam("NIFisDupe", isDupe);
PrimeFaces.current().ajax().addCallbackParam("formattedNIF", this.nif);
}
public List<FamilyDoctorTO> getFamilyDoctorList() {
return familyDoctorList;
}
/**
* Método que implementa la búsqueda de un médico de familia a través del termino tecleado por el usuario en la lista de selección
*
* @param query Termino tecleado por el usuario
* @return Lista de médicos de familia que coinciden con el termino búscado por el usuario.
*/
public List<FamilyDoctorTO> completeFamilyDoctor(String query) {
if (query != null && query.equals(this.lastUIQueryFD) == false) {
this.lastUIQueryFD = query;
@@ -255,6 +303,18 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
return id;
}
/**
* Método que guarda los datos realizados en la modificación del perfil.
* Tiene en cuenta el tipo de usuario que está editando su perfil.
*
* Si el usuario es un médico de familia requiere que se seleccione un CAP para el usuario.
* Si el usuario es un médico especialista requiere que se seleccione una especialidad médica para el usuario.
* Se comprueba que el NIF especificado sea válido y no pertenezca a otro usuario registrado (ver relgas de NIF permitidos para usuarios en el método handleNIFValueChange)
*
* Si se especifica una nueva contraseña, entonces se realiz un cambio de contraseña, y se requiere además: Que la nueva contraseña sea diferente a la anterior.
*
* Después de guardar los datos, se actualizan los datos guardados en la sesión actual para reflejar un posible cambio de nombre y/o apellidos.
*/
public void saveData() {
int error = 0;
@@ -262,6 +322,8 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
if (this.userType == null)
return;
this.nif = ValidationUtils.normalizeNIF(this.nif);
boolean changePassword = (this.oldPassword != null && this.oldPassword.equals("") == false) || (this.password != null && this.password.equals("") == false);
if (this.isUserTypeFamilyDoctor() && this.primaryHealthCareCenter == null) {
@@ -295,20 +357,25 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
if (error == 0) {
try {
LoggedUserTO usr = null;
switch (this.userType) {
case PATIENT:
PatientTO pat = this.getRemoteManagerProfile().updatePatientData(id, nif, name, surname, password, email);
this.setPatientData(pat);
usr = new LoggedUserTO(pat.getId().toString(), pat.getName(), pat.getPassword(), this.userType, pat.getDisplayName());
break;
case FAMILY_DOCTOR:
FamilyDoctorTO fd = this.getRemoteManagerProfile().updateFamilyDoctorData(id, nif, name, surname, password, email, this.primaryHealthCareCenter);
this.setFamilyDoctorData(fd);
usr = new LoggedUserTO(fd.getId().toString(), fd.getName(), fd.getPassword(), this.userType, fd.getDisplayName());
break;
case SPECIALIST_DOCTOR:
SpecialistDoctorTO sd = this.getRemoteManagerProfile().updateSpecialistDoctorData(id, nif, name, surname, password, email, this.medicalSpecialty);
this.setSpecialistDoctorData(sd);
usr = new LoggedUserTO(sd.getId().toString(), sd.getName(), sd.getPassword(), this.userType, sd.getDisplayName());
break;
case ADMINISTRATOR:
@@ -321,6 +388,9 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
this.oldPassword = "";
}
// Actualizamos la sessión del usuario actual por si ha cambiado el nombre de usuario.
SessionUtils.createOrUpdateSession(usr);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de su perfil se han guardado correctamente.");
} catch (Exception e) {
this.manageException(e);

View File

@@ -0,0 +1,88 @@
package managedbean.systemAdmin;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.FamilyDoctorTO;
import TO.PrimaryHealthCareCenterTO;
import common.Constants;
import managedbean.common.ManagedBeanBase;
@Named("listDoctors")
@ViewScoped
public class ListDoctorsByCenterMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private List<PrimaryHealthCareCenterTO> primaryHealthCareCenterList;
private PrimaryHealthCareCenterTO primaryHealthCareCenter;
private String lastUIQueryPH;
private LazyDataModel<FamilyDoctorTO> lazyDataModelDoctorList;
public ListDoctorsByCenterMBean() {
}
@PostConstruct
public void init() {
this.primaryHealthCareCenterList = this.getRemoteManagerCommon().listCAPsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
this.primaryHealthCareCenter = null;
this.lastUIQueryPH = "";
this.lazyDataModelDoctorList = new LazyDataModel<FamilyDoctorTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<FamilyDoctorTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
if (primaryHealthCareCenter == null) {
this.setRowCount(0);
return null;
} else {
Long totalRowCount = getRemoteManagerMedicalTest().getSpecialistDoctorByMedicalSpecialityCount(primaryHealthCareCenter.getId());
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerSystemAdmin().listAllFamilyDoctorsByCAPPaged(primaryHealthCareCenter.getId(), (first / pageSize), pageSize);
}
}
};
}
public LazyDataModel<FamilyDoctorTO> getLazyDataModelDoctorList() {
return lazyDataModelDoctorList;
}
public List<PrimaryHealthCareCenterTO> completePrimaryHealCareCenter(String query) {
if (query != null && query.equals(this.lastUIQueryPH) == false) {
this.lastUIQueryPH = query;
this.primaryHealthCareCenterList = this.getRemoteManagerCommon().listCAPsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.primaryHealthCareCenterList;
}
public List<PrimaryHealthCareCenterTO> getPrimaryHealthCareCenterList() {
return primaryHealthCareCenterList;
}
public void setPrimaryHealthCareCenterList(List<PrimaryHealthCareCenterTO> value) {
this.primaryHealthCareCenterList = value;
}
public PrimaryHealthCareCenterTO getPrimaryHealthCareCenter() {
return primaryHealthCareCenter;
}
public void setPrimaryHealthCareCenter(PrimaryHealthCareCenterTO value) {
this.primaryHealthCareCenter = value;
}
public Long getPatientsByDoctor(int familyDoctorId) {
return getRemoteManagerSystemAdmin().getPatientCount(familyDoctorId);
}
}

View File

@@ -1,19 +1,13 @@
package managedbean.systemAdmin;
import java.util.Properties;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.http.HttpSession;
import org.primefaces.PrimeFaces;
import TO.LoggedUserTO;
import ejb.systemAdmin.SystemAdminFacadeRemote;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@@ -52,26 +46,44 @@ public class LoginMBean extends ManagedBeanBase {
if (usr != null) {
loggedIn = true;
SessionUtils.CreateSession(usr);
SessionUtils.createOrUpdateSession(usr);
this.addFacesMessageKeep(FacesMessage.SEVERITY_INFO, "Login correcto", "Bienvenido " + usr.getName());
viewRedirect = "/home?faces-redirect=true";
} else
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Loggin Error", "El usuario o la contraseña son incorrectos");
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "El usuario o la contraseña son incorrectos");
} catch (Exception ex) {
this.addFacesMessage(FacesMessage.SEVERITY_FATAL, "Error fatal", ex.getMessage());
}
} else
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Loggin Error", "El usuario o la contraseña son incorrectos");
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Login Error", "El usuario o la contraseña son incorrectos");
PrimeFaces.current().ajax().addCallbackParam("loggedIn", loggedIn);
return viewRedirect;
}
/**
* Realiza un login semi-automatico. Por ejemplo desde el filtro de autorización.
* Se debe utilizar con propositos de depuración, para evitar realizar el login manual.
*
* @param ses
*/
public boolean autoLogin(HttpSession ses) {
//TODO: Eliminar este metodo al terminar el desarrollo.
boolean bResult = false;
LoggedUserTO usr = this.getRemoteManagerSystemAdmin().login(username, password);
if (usr != null) {
SessionUtils.createOrUpdateSession(ses, usr);
bResult = true;
}
return bResult;
}
// logout event, invalidate session
public String logout() {
this.addFacesMessageKeep(FacesMessage.SEVERITY_INFO, "Sessión cerrada", "Ha cerrado correctament su ssesión. Hasta la vista");
this.addFacesMessageKeep(FacesMessage.SEVERITY_INFO, "Sessión cerrada", "Ha cerrado correctament su sesión. Hasta la vista");
SessionUtils.DestroySession();

View File

@@ -0,0 +1,173 @@
package managedbean.systemAdmin;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.primefaces.event.RowEditEvent;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.PrimaryHealthCareCenterTO;
import managedbean.common.ManagedBeanBase;
@Named("ManageHealthCareCenters")
@ViewScoped
public class ManageHealthCareCentersMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String location;
private PrimaryHealthCareCenterTO primaryHealthCareCenter;
private LazyDataModel<PrimaryHealthCareCenterTO> lazyDataModelCAPsList;
public ManageHealthCareCentersMBean() {
}
@PostConstruct
public void init() {
this.lazyDataModelCAPsList = new LazyDataModel<PrimaryHealthCareCenterTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<PrimaryHealthCareCenterTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
Long totalRowCount = getRemoteManagerSystemAdmin().getCAPCount();
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerSystemAdmin().listCAPsPaged((first / pageSize), pageSize);
}
};
}
public LazyDataModel<PrimaryHealthCareCenterTO> getlazyDataModelCAPsList() {
return lazyDataModelCAPsList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
private void showPrimaryHealthCareCenterData(PrimaryHealthCareCenterTO cap) {
this.primaryHealthCareCenter = cap;
if (cap == null) {
this.id = null;
this.name = "";
this.location = "";
} else {
this.id = cap.getId();
this.name = cap.getName();
this.location = cap.getLocation();
}
}
public PrimaryHealthCareCenterTO getPrimaryHealthCareCenter() {
return primaryHealthCareCenter;
}
public void setPrimaryHealthCareCenter(PrimaryHealthCareCenterTO value) {
this.primaryHealthCareCenter = value;
}
public void onRowEdit(RowEditEvent event) {
int error = 0;
if (((PrimaryHealthCareCenterTO) event.getObject()).getName() == null || ((PrimaryHealthCareCenterTO) event.getObject()).getName().trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Nombre no relleno", "Por favor, escriba un nombre para el centro.");
error++;
}
if (((PrimaryHealthCareCenterTO) event.getObject()).getLocation() == null || ((PrimaryHealthCareCenterTO) event.getObject()).getLocation().trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Localización no rellena", "Por favor, escriba una localización.");
error++;
}
if (error == 0) {
try {
this.getRemoteManagerSystemAdmin().updateHealthCareCenter(((PrimaryHealthCareCenterTO) event.getObject()).getId(), ((PrimaryHealthCareCenterTO) event.getObject()).getName(),
((PrimaryHealthCareCenterTO) event.getObject()).getLocation());
this.showPrimaryHealthCareCenterData(null);
FacesMessage msg = new FacesMessage("CAP editado", ((PrimaryHealthCareCenterTO) event.getObject()).getName());
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (Exception e) {
this.manageException(e);
}
}
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Edición cancelada", ((PrimaryHealthCareCenterTO) event.getObject()).getName());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void deleteDataById(Integer id) throws IOException {
try {
this.getRemoteManagerSystemAdmin().deleteHealthCareCenter(id);
this.showPrimaryHealthCareCenterData(null);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "El CAP se ha borrado", "Los datos del Centro de Atención Primaria se han borrado correctamente.");
} catch (Exception e) {
this.manageException(e);
}
}
public void insertData() {
int error = 0;
if (name == null || name.trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Nombre no relleno", "Por favor, escriba un nombre para el centro.");
error++;
}
if (location == null || location.trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Localización no rellena", "Por favor, escriba una localización.");
error++;
}
if (this.getRemoteManagerSystemAdmin().findHealthCareCenterByName(name) != null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "CAP ya existente", "El CAP ya se encuentra en la base de datos");
error++;
}
if (error == 0) {
try {
this.getRemoteManagerSystemAdmin().insertHealthCareCenter(name, location);
this.showPrimaryHealthCareCenterData(null);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos del Centro de Atención Primaria se han guardado correctamente.");
} catch (Exception e) {
this.manageException(e);
}
}
}
}

View File

@@ -10,7 +10,6 @@ import javax.inject.Named;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import common.Constants;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@@ -43,13 +42,17 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Sesión no válida",
"Su sesión actual no es válida, por favor cierre su sesión y vuelva a logearse en el sistema.");
else {
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
this.refreshFormData();
}
} catch (Exception e) {
this.manageException(e);
}
}
private void refreshFormData() {
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listAllMedicalSpecialities();
}
public Integer getId() {
return id;
}
@@ -74,11 +77,19 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
this.description = description;
}
private void setSpecialtyData(MedicalSpecialtyTO ms) {
private void showSpecialtyData(MedicalSpecialtyTO ms) {
this.medicalSpecialty = ms;
if (ms == null) {
this.id = null;
this.name = "";
this.description = "";
} else {
this.id = ms.getId();
this.name = ms.getName();
this.description = ms.getDescription();
}
}
public List<MedicalSpecialtyTO> getMedicalSpecialtiesList() {
return medicalSpecialitiesList;
@@ -95,19 +106,21 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
public void saveData() {
int error = 0;
if (this.medicalSpecialty.getName() == null) {
if (this.medicalSpecialty.getName() == null || this.medicalSpecialty.getName().trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Nombre no relleno", "Por favor, escriba un nombre de especialidad.");
error++;
}
if (this.medicalSpecialty.getDescription() == null) {
if (this.medicalSpecialty.getDescription() == null || this.medicalSpecialty.getDescription().trim().length() == 0) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Descripción no rellena", "Por favor, escriba una descripción.");
error++;
}
if (error == 0) {
try {
MedicalSpecialtyTO ms = this.getRemoteManagerSystemAdmin().updateSpecialtyData(this.medicalSpecialty.getId(), this.medicalSpecialty.getName(), this.medicalSpecialty.getDescription());
this.setSpecialtyData(ms);
this.getRemoteManagerSystemAdmin().updateSpecialty(this.medicalSpecialty.getId(), this.medicalSpecialty.getName(),this.medicalSpecialty.getDescription());
this.showSpecialtyData(null);
this.refreshFormData();
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de la especialidad se han guardado correctamente.");
} catch (Exception e) {
this.manageException(e);
@@ -129,8 +142,11 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
if (error == 0) {
try {
this.getRemoteManagerSystemAdmin().deleteSpecialtyData(this.medicalSpecialty.getId(), this.medicalSpecialty.getName(), this.medicalSpecialty.getDescription());
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los especialidad se ha borrado", "Los datos de la especialidad se han borrado correctamente.");
this.getRemoteManagerSystemAdmin().deleteSpecialty(this.medicalSpecialty.getId());
this.showSpecialtyData(null);
this.refreshFormData();
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "La especialidad se ha borrado", "Los datos de la especialidad se han borrado correctamente.");
} catch (Exception e) {
this.manageException(e);
}
@@ -149,10 +165,17 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
error++;
}
if (this.getRemoteManagerSystemAdmin().findSpecialtyByName(name) != null) {
this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Especialidad ya existente", "La especialidad ya se encuentra en la base de datos");
error++;
}
if (error == 0) {
try {
MedicalSpecialtyTO ms = this.getRemoteManagerSystemAdmin().insertSpecialtyData(name, description);
this.setSpecialtyData(ms);
this.getRemoteManagerSystemAdmin().insertSpecialty(name, description);
this.showSpecialtyData(null);
this.refreshFormData();
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de la especialidad se han guardado correctamente.");
} catch (Exception e) {
this.manageException(e);

View File

@@ -14,12 +14,12 @@ import javax.faces.validator.ValidatorException;
import org.primefaces.validate.ClientValidator;
@FacesValidator("emailValidator")
public class EmailValidator implements Validator, ClientValidator {
public class EmailValidator implements Validator<String>, ClientValidator {
private final static String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
private final static Pattern EMAIL_COMPILED_PATTERN = Pattern.compile(EMAIL_PATTERN);
public void validate(FacesContext context, UIComponent comp, Object value) throws ValidatorException {
public void validate(FacesContext context, UIComponent comp, String value) throws ValidatorException {
String strValue = "";
if (value != null)

View File

@@ -14,19 +14,20 @@ import org.primefaces.validate.ClientValidator;
import managedbean.common.ValidationUtils;
@FacesValidator("nifValidator")
public class NifValidator implements Validator, ClientValidator {
public class NifValidator implements Validator<String>, ClientValidator {
public void validate(FacesContext context, UIComponent comp, Object value) throws ValidatorException {
public void validate(FacesContext context, UIComponent comp, String value) throws ValidatorException {
String strValue = "";
if (value != null)
strValue = String.valueOf(value);
if (strValue.equals(""))
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "El NIF no es válido", "El NIF " + value + " no es válido"));
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "El NIF no es válido", "El NIF " + strValue + " no es válido"));
strValue = ValidationUtils.normalizeNIF(strValue);
if (ValidationUtils.isValid(strValue) == false)
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "El NIF no es válido", "El NIF " + value + " no es válido"));
throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "El NIF no es válido", "El NIF " + strValue + " no es válido"));
}
public Map<String, Object> getMetadata() {

View File

@@ -0,0 +1,140 @@
package managedbean.visit;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import TO.FamilyDoctorTO;
import TO.PatientTO;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("AddVisit")
@ViewScoped
public class AddVisitMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private LocalDate date;
private LocalTime time;
private String observations;
private String result;
private String patientDisplayName;
private String familyDoctorDisplayName;
private PatientTO patient;
private FamilyDoctorTO familyDoctor;
public AddVisitMBean() {
}
@PostConstruct
public void init() {
// El usuario actual es un medico de familia, recuperamos su Id de la sessión actual
try {
Integer patientId = Integer.valueOf(SessionUtils.getUserId());
this.patient = this.getRemoteManagerCommon().findPatientById(patientId);
this.familyDoctor = this.patient.getFamilyDoctor();
this.date = LocalDate.now();
} catch (Exception e) {
this.manageException(e);
}
}
public void saveData() {
// Comprobamos que la fecha fijada para la visita no sea anterior a la actual
int error = 0;
LocalDate today = LocalDate.now();
if (this.date.isBefore(today)) {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
error++;
}
if (this.date.equals(today) && this.time.isBefore(LocalTime.now())) {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
error++;
}
if (error == 0) {
try {
this.getRemoteManagerVisit().addVisit(this.patient.getId(), this.date, this.time, this.observations);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Visita creada", "La nueva visita se ha registrado correctamente en el sistema.");
} catch (Exception e) {
this.manageException(e);
}
}
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public String getObservations() {
return observations;
}
public void setObservations(String observations) {
this.observations = observations;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getPatientDisplayName() {
return patientDisplayName;
}
public String getFamilyDoctorDisplayName() {
return familyDoctorDisplayName;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
public FamilyDoctorTO getFamilyDoctor() {
return familyDoctor;
}
public void setFamilyDoctor(FamilyDoctorTO familyDoctor) {
this.familyDoctor = familyDoctor;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
}

View File

@@ -0,0 +1,133 @@
package managedbean.visit;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.PatientTO;
import TO.VisitTO;
import common.Constants;
import common.UserType;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("PatientVisitList")
@ViewScoped
public class PatientVisitListMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private PatientTO patient;
private Integer patientId;
private LazyDataModel<VisitTO> lazyDataModelVisitList;
private LocalDate selectedDate;
private String lastUIQuery;
private List<PatientTO> patientList;
public PatientVisitListMBean() {
}
@PostConstruct
public void init() {
this.lastUIQuery = "";
// Si el usuario es un paciente listamos las visitas de ese paciente, si es admnistrador listamos todas.
switch (SessionUtils.getUserType()) {
case ADMINISTRATOR:
this.patientId = null;
this.patient = null;
this.selectedDate = LocalDate.now();
this.patientList = this.getRemoteManagerCommon().listPatientsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
break;
case PATIENT:
this.patientId = Integer.valueOf(SessionUtils.getUserId());
this.patient = this.getRemoteManagerCommon().findPatientById(patientId);
this.selectedDate = null;
break;
case FAMILY_DOCTOR:
case SPECIALIST_DOCTOR:
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
return;
}
this.lazyDataModelVisitList = new LazyDataModel<VisitTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<VisitTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
if (patient != null)
patientId = patient.getId();
else
patientId = null;
Long totalRowCount = getRemoteManagerVisit().getVisitsCount(patientId, selectedDate);
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerVisit().listVisitsPaged(patientId, selectedDate, (first / pageSize), pageSize);
}
};
}
public List<PatientTO> completePatient(String query) {
if (query != null && query.equals(this.lastUIQuery) == false) {
this.lastUIQuery = query;
// Recuperamos las 200 primeras coincidencias
this.patientList = this.getRemoteManagerCommon().listPatientsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
}
return this.patientList;
}
public List<PatientTO> getPatientList() {
return patientList;
}
public void removeVisit(Integer visitId) throws IOException {
this.getRemoteManagerVisit().removeVisit(visitId);
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Visita eliminada", String.format("La visita con Id: %d se ha eliminado correctamente", visitId));
}
public void editVisit(Integer visitId) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
ctx.getExternalContext().redirect(String.format("UpdateVisit.xhtml?id=%d&fromPage=%s", visitId, ctx.getViewRoot().getViewId()));
}
public LazyDataModel<VisitTO> getLazyDataModelVisitList() {
return lazyDataModelVisitList;
}
public void showData() {
}
public LocalDate getSelectedDate() {
return selectedDate;
}
public void setSelectedDate(LocalDate selectedDate) {
this.selectedDate = selectedDate;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
public boolean isAdmin() {
return SessionUtils.getUserType() == UserType.ADMINISTRATOR;
}
}

View File

@@ -0,0 +1,198 @@
package managedbean.visit;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import TO.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("UpdateVisit")
@ViewScoped
public class UpdateVisitMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private LocalDate date;
private LocalTime time;
private String observations;
private String result;
private PatientTO patient;
private FamilyDoctorTO familyDoctor;
private boolean onlyResult;
private String fromPage;
public UpdateVisitMBean() {
}
@PostConstruct
public void init() {
FacesContext context = FacesContext.getCurrentInstance();
Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
VisitTO vi = null;
try {
this.fromPage = requestParams.get("fromPage");
// Parámetro con el "id" de la visita.
int parId = Integer.valueOf(requestParams.get("id"));
vi = this.getRemoteManagerVisit().getVisit(parId);
} catch (Exception e) {
this.manageException(e);
}
if (vi != null) {
this.id = vi.getId();
this.date = vi.getDate();
this.time = vi.getTime();
this.observations = vi.getObservations();
this.result = vi.getResult();
this.patient = vi.getPatient();
this.familyDoctor = vi.getFamilyDoctor();
} else {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Identificador de visita no válido",
"No se ha podido recuperar el identificador de visita especificado. Por favor, vuelva a intentarlo seleccionando de nuevo la visita.");
}
// Si el usuario es un paciente listamos las visitas de ese paciente, si es
// admnistrador listamos todas.
switch (SessionUtils.getUserType()) {
case ADMINISTRATOR:
case PATIENT:
// Administrador y paciente pueden actualizar cualquier dato de la visita
// (excepto esl resultado)
this.onlyResult = false;
break;
case FAMILY_DOCTOR:
// El médico de familia solo puede actualizar el resultado.
this.onlyResult = true;
break;
case SPECIALIST_DOCTOR:
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
return;
}
}
public void saveData() {
try {
switch (SessionUtils.getUserType()) {
case ADMINISTRATOR:
case PATIENT:
// Administrador y paciente pueden actualizar la fecha y hora de la visita (excepto el resultado)
// Comprobamos que la fecha fijada para la visita no sea anterior a la actual
int error = 0;
LocalDate today = LocalDate.now();
if (this.date.isBefore(today)) {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
error++;
}
if (this.date.equals(today) && this.time.isBefore(LocalTime.now())) {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Fecha incorrecta", "La cita fijada es anterior al momento actual");
error++;
}
if (error == 0) {
this.getRemoteManagerVisit().updateVisit(this.id, this.date, this.time);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Visita actualizada", "La fecha y hora de la visita se ha actualizado correctamente.");
}
break;
case FAMILY_DOCTOR:
// El médico de familia solo puede actualizar el resultado.
// TODO: implementar método EJB para actualizar el resultado.
this.getRemoteManagerVisit().addResultToVisit(this.id, this.result);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Resultado actualizado", "El resultado de la visita se ha actualizado correctamente.");
break;
case SPECIALIST_DOCTOR:
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Acesso denegado", "Su perfil de usuario no está autorizado acceder a esta página.");
return;
}
} catch (Exception e) {
this.manageException(e);
}
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public String getObservations() {
return observations;
}
public void setObservations(String observations) {
this.observations = observations;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
public FamilyDoctorTO getFamilyDoctor() {
return familyDoctor;
}
public void setFamilyDoctor(FamilyDoctorTO familyDoctor) {
this.familyDoctor = familyDoctor;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isOnlyResult() {
return onlyResult;
}
public void setOnlyResult(boolean onlyResult) {
this.onlyResult = onlyResult;
}
public String getFromPage() {
return fromPage;
}
public void setFromPage(String fromPage) {
this.fromPage = fromPage;
}
}

View File

@@ -0,0 +1,84 @@
package managedbean.visit;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.VisitTO;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("VisitList")
@ViewScoped
public class VisitListMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private int familyDoctorId;
private String familyDoctorDisplayName;
private LazyDataModel<VisitTO> lazyDataModelVisitList;
private LocalDate selectedDate;
public VisitListMBean() {
}
@PostConstruct
public void init() {
// El usuario actual es un medico de familia, recuperamos su Id de la sessión actual
this.familyDoctorId = Integer.valueOf(SessionUtils.getUserId());
this.familyDoctorDisplayName = SessionUtils.getUserDisplayName();
this.selectedDate = LocalDate.now();
this.lazyDataModelVisitList = new LazyDataModel<VisitTO>() {
private static final long serialVersionUID = 1L;
@Override
public List<VisitTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
Long totalRowCount = getRemoteManagerVisit().getScheduledVisitsCount(familyDoctorId, selectedDate);
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerVisit().listAllScheduledVisitsPaged(familyDoctorId, selectedDate, (first / pageSize), pageSize);
}
};
}
public LazyDataModel<VisitTO> getLazyDataModelVisitList() {
return lazyDataModelVisitList;
}
public void showData() {
}
public void showVisit(Integer visitId) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
ctx.getExternalContext().redirect(String.format("VisitView.xhtml?id=%d&fromPage=%s", visitId, ctx.getViewRoot().getViewId()));
}
public void editVisit(Integer visitId) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
ctx.getExternalContext().redirect(String.format("UpdateVisit.xhtml?id=%d&fromPage=%s", visitId, ctx.getViewRoot().getViewId()));
}
public LocalDate getSelectedDate() {
return selectedDate;
}
public void setSelectedDate(LocalDate selectedDate) {
this.selectedDate = selectedDate;
}
public String getFamilyDoctorDisplayName() {
return familyDoctorDisplayName;
}
}

View File

@@ -1,28 +1,141 @@
package managedbean.visit;
import java.io.IOException;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import TO.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
import managedbean.common.ManagedBeanBase;
@Named("VisitMBean")
@RequestScoped
@Named("VisitView")
@ViewScoped
public class VisitMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private LocalDate date;
private LocalTime time;
private String observations;
private String result;
private PatientTO patient;
private FamilyDoctorTO familyDoctor;
private String fromPage;
public VisitMBean() {
}
@PostConstruct
public void init() {
// Inicialización de variables y propiedades van aquí.
FacesContext context = FacesContext.getCurrentInstance();
// Como realizar llamadas al EJB Remoto
// this.getRemoteManagerSystemAdmin().MetodoEJB
Map<String, String> requestParams = context.getExternalContext().getRequestParameterMap();
VisitTO vi = null;
try {
this.fromPage = requestParams.get("fromPage");
// Parámetro con el "id" de la visita.
int parId = Integer.valueOf(requestParams.get("id"));
vi = this.getRemoteManagerVisit().getVisit(parId);
} catch (Exception e) {
this.manageException(e);
}
if (vi != null) {
this.id = vi.getId();
this.date = vi.getDate();
this.time = vi.getTime();
this.observations = vi.getObservations();
this.result = vi.getResult();
this.patient = vi.getPatient();
this.familyDoctor = vi.getFamilyDoctor();
} else {
this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Identificador de visita no válido",
"No se ha podido recuperar el identificador de visita especificado. Por favor, vuelva a intentarlo seleccionando de nuevo la visita.");
}
}
public void editVisit(Integer visitId) throws IOException {
FacesContext ctx = FacesContext.getCurrentInstance();
ctx.getExternalContext().redirect(String.format("UpdateVisit.xhtml?id=%d&fromPage=%s", visitId, this.fromPage));
}
public LocalDate getDate() {
return date;
}
public void setDate(LocalDate date) {
this.date = date;
}
public LocalTime getTime() {
return time;
}
public void setTime(LocalTime time) {
this.time = time;
}
public String getObservations() {
return observations;
}
public void setObservations(String observations) {
this.observations = observations;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
public FamilyDoctorTO getFamilyDoctor() {
return familyDoctor;
}
public void setFamilyDoctor(FamilyDoctorTO familyDoctor) {
this.familyDoctor = familyDoctor;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFromPage() {
return fromPage;
}
public void setFromPage(String fromPage) {
this.fromPage = fromPage;
}
}

5
1.sources/MyHealth/start.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/bash
ant
read -p "Di hola pringao!" asd

View File

@@ -70,13 +70,13 @@ if exists (SELECT 1 FROM pg_sequences WHERE schemaname='myhealth' and sequencena
drop sequence myhealth.codigoidentificacionpaciente;
end if;
CREATE SEQUENCE myhealth.ProfesionalNumber
CREATE SEQUENCE myhealth.profesionalnumber
INCREMENT 1
START 1000
MINVALUE 1000
CACHE 1;
CREATE SEQUENCE myhealth.CodigoIdentificacionPaciente
CREATE SEQUENCE myhealth.codigoidentificacionpaciente
INCREMENT 1
START 1000
MINVALUE 1000
@@ -170,11 +170,11 @@ CREATE TABLE myhealth.visit
(
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
date date NOT NULL,
"time" abstime NOT NULL,
"time" time NOT NULL,
observations TEXT COLLATE pg_catalog."default",
result TEXT COLLATE pg_catalog."default",
patientid INTEGER REFERENCES myhealth.patient(id),
familydoctorid INTEGER REFERENCES myhealth.familydoctor(id),
patientid INTEGER REFERENCES myhealth.patient(id) NOT NULL,
familydoctorid INTEGER REFERENCES myhealth.familydoctor(id) NOT NULL,
CONSTRAINT visit_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
@@ -197,11 +197,11 @@ TABLESPACE pg_default;
CREATE TABLE myhealth.medicaltest
(
id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
date date NOT NULL,
"time" abstime NOT NULL,
date DATE NOT NULL,
"time" TIME NOT NULL,
observations TEXT COLLATE pg_catalog."default",
highresimage TEXT,
type VARCHAR(30) NOT NULL,
type VARCHAR(50) NOT NULL,
patientid INTEGER REFERENCES myhealth.patient(id) NOT NULL,
specialistdoctorid INTEGER REFERENCES myhealth.specialistdoctor(id) NOT NULL,
CONSTRAINT medicaltest_pkey PRIMARY KEY (id)
@@ -218,6 +218,8 @@ ALTER TABLE myhealth.specialistdoctor OWNER to "USER";
ALTER TABLE myhealth.visit OWNER to "USER";
ALTER TABLE myhealth.question OWNER to "USER";
ALTER TABLE myhealth.medicaltest OWNER to "USER";
ALTER SEQUENCE myhealth.profesionalnumber OWNER to "USER";
ALTER SEQUENCE myhealth.codigoidentificacionpaciente OWNER to "USER";
-- Permisos para la máquina de PRE (usuario: usrmyhealth)
GRANT ALL ON myhealth.administrator to usrmyhealth;
@@ -229,6 +231,8 @@ GRANT ALL ON myhealth.specialistdoctor to usrmyhealth;
GRANT ALL ON myhealth.visit to usrmyhealth;
GRANT ALL ON myhealth.question to usrmyhealth;
GRANT ALL ON myhealth.medicaltest to usrmyhealth;
GRANT ALL ON myhealth.profesionalnumber to usrmyhealth;
GRANT ALL ON myhealth.codigoidentificacionpaciente to usrmyhealth;
END;
$$

View File

@@ -1,4 +1,4 @@
--Inserta usuarios administradores (contraseña Hash MD5 'admin' para todos)
-- Inserta usuarios administradores (contraseña Hash MD5 'admin' para todos)
insert into myhealth.administrator (email, password) values
('admin@example.com', '21232F297A57A5A743894A0E4A801FC3')
,('marcos@example.com', '21232F297A57A5A743894A0E4A801FC3');
@@ -24,62 +24,571 @@ INSERT INTO myhealth.primaryhealthcarecenter(name, location) VALUES
-- Inserta Especialidades médicas
insert into MyHealth.MedicalSpecialty(name, description) values
('Alergologia','Especialidad médica de Alergologia')
,('Cirugía cardiaca','Especialidad médica de Cirugía cardiaca')
,('Cirugía general','Especialidad médica de Cirugía general')
,('Cirugía plastica','Especialidad médica de Cirugía plastica')
,('Cirugía de mama','Especialidad médica de Cirugía de mama')
,('Cirugía maxilofacial','Especialidad médica de Cirugía maxilofacial')
,('Cirugía vascular','Especialidad médica de Cirugía vascular')
,('Dermatología','Especialidad médica de Dermatología')
,('Endocrinología y nutrición','Especialidad médica de Endocrinología y nutrición')
,('Gastroenterología- digestivo','Especialidad médica de Gastroenterología- digestivo')
,('Neurocirugía','Especialidad médica de Neurocirugía')
,('Oftalmología','Especialidad médica de Oftalmología')
,('Otorrinolaringologia','Especialidad médica de Otorrinolaringologia')
,('Oncología','Especialidad médica de Oncología')
,('Pediatría','Especialidad médica de Pediatría');
('Alergia','Especialidad médica en Alergia'),
('Alergia Infantil','Especialidad médica en Alergia Infantil'),
('Anatomia Patologica','Especialidad médica en Anatomia Patologica'),
('Anatomia Bucalmaxilofacial','Especialidad médica en Anatomia Bucalmaxilofacial'),
('Andrologia','Especialidad médica en Andrologia'),
('Anestesiologia','Especialidad médica en Anestesiologia'),
('Bioquimica','Especialidad médica en Bioquimica'),
('Biotecnologia','Especialidad médica en Biotecnologia'),
('Bromatologia','Especialidad médica en Bromatologia'),
('Bucomaxilofacial','Especialidad médica en Bucomaxilofacial'),
('Cardioangiologia','Especialidad médica en Cardioangiologia'),
('Cardiologia','Especialidad médica en Cardiologia'),
('Cardiologia Geriatrica','Especialidad médica en Cardiologia Geriatrica'),
('Cardiologia Pediatrica','Especialidad médica en Cardiologia Pediatrica'),
('Cirugia Bucomaxilofacial','Especialidad médica en Cirugia Bucomaxilofacial'),
('Cirugia Cardiovascular','Especialidad médica en Cirugia Cardiovascular'),
('Cirugia De Cabeza/Cuello','Especialidad médica en Cirugia De Cabeza/Cuello'),
('Cirugia Gastroenterolog.','Especialidad médica en Cirugia Gastroenterolog.'),
('Cirugia General','Especialidad médica en Cirugia General'),
('Cirugia Infantil','Especialidad médica en Cirugia Infantil'),
('Cirugia Oncologica','Especialidad médica en Cirugia Oncologica'),
('Cirugia Plastica','Especialidad médica en Cirugia Plastica'),
('Cirugia Proctologica','Especialidad médica en Cirugia Proctologica'),
('Cirugia Toraxica','Especialidad médica en Cirugia Toraxica'),
('Cirugia Vascular','Especialidad médica en Cirugia Vascular'),
('Citologia','Especialidad médica en Citologia'),
('Clinica Estomatologica','Especialidad médica en Clinica Estomatologica'),
('Clinica Medica','Especialidad médica en Clinica Medica'),
('Dermatologia','Especialidad médica en Dermatologia'),
('Dermatologia Infantil','Especialidad médica en Dermatologia Infantil'),
('Diabetes','Especialidad médica en Diabetes'),
('Diagnostico Por Imagenes','Especialidad médica en Diagnostico Por Imagenes'),
('Ecografia','Especialidad médica en Ecografia'),
('Electromiografia','Especialidad médica en Electromiografia'),
('Endocrinologia','Especialidad médica en Endocrinologia'),
('Endocrinologia Infantil','Especialidad médica en Endocrinologia Infantil'),
('Endocrinologia/Nuticion','Especialidad médica en Endocrinologia/Nuticion'),
('Endodoncia','Especialidad médica en Endodoncia'),
('Esterilidad Femenina','Especialidad médica en Esterilidad Femenina'),
('Fisiatria','Especialidad médica en Fisiatria'),
('Flebologia','Especialidad médica en Flebologia'),
('Forense','Especialidad médica en Forense'),
('Gastroenterologia','Especialidad médica en Gastroenterologia'),
('Gastroenterologia Infantil','Especialidad médica en Gastroenterologia Infantil'),
('Genetica','Especialidad médica en Genetica'),
('Geriatria Y Gerontologia','Especialidad médica en Geriatria Y Gerontologia'),
('Ginecologia','Especialidad médica en Ginecologia'),
('Ginecologia Infanto-Juvenil','Especialidad médica en Ginecologia Infanto-Juvenil'),
('Hematologia','Especialidad médica en Hematologia'),
('Hematologia Infantil','Especialidad médica en Hematologia Infantil'),
('Hematologia Oncologica','Especialidad médica en Hematologia Oncologica'),
('Hemodinamia','Especialidad médica en Hemodinamia'),
('Hemostasia','Especialidad médica en Hemostasia'),
('Hemoterapia','Especialidad médica en Hemoterapia'),
('Hepatologia','Especialidad médica en Hepatologia'),
('Infectologia','Especialidad médica en Infectologia'),
('Infectologia Pediatrica','Especialidad médica en Infectologia Pediatrica'),
('Inmunologia','Especialidad médica en Inmunologia'),
('Inmunologia Infantil','Especialidad médica en Inmunologia Infantil'),
('Kinesiologia Cadíaca','Especialidad médica en Kinesiologia Cadíaca'),
('Kinesiologia En Pediatria','Especialidad médica en Kinesiologia En Pediatria'),
('Kinesiologia En Traumatologia','Especialidad médica en Kinesiologia En Traumatologia'),
('Kinesiologia General','Especialidad médica en Kinesiologia General'),
('Linfologia','Especialidad médica en Linfologia'),
('Medicina Del Deporte','Especialidad médica en Medicina Del Deporte'),
('Medicina Del Trabajo / Laboral','Especialidad médica en Medicina Del Trabajo / Laboral'),
('Medicina Legal','Especialidad médica en Medicina Legal'),
('Medicina Nuclear','Especialidad médica en Medicina Nuclear'),
('Nefrologia','Especialidad médica en Nefrologia'),
('Nefrologia Infantil','Especialidad médica en Nefrologia Infantil'),
('Neonatologia','Especialidad médica en Neonatologia'),
('Neumonologia','Especialidad médica en Neumonologia'),
('Neumonologia Infantil','Especialidad médica en Neumonologia Infantil'),
('Neumotisiologia','Especialidad médica en Neumotisiologia'),
('Neumotisiologia Infantil','Especialidad médica en Neumotisiologia Infantil'),
('Neurocirugia','Especialidad médica en Neurocirugia'),
('Neurofisiologia','Especialidad médica en Neurofisiologia'),
('Neurofoniatria','Especialidad médica en Neurofoniatria'),
('Neurologia','Especialidad médica en Neurologia'),
('Neurologia Infantil','Especialidad médica en Neurologia Infantil'),
('Neuropsiquiatria','Especialidad médica en Neuropsiquiatria'),
('Nutricion','Especialidad médica en Nutricion'),
('Nutricion Infantil','Especialidad médica en Nutricion Infantil'),
('Obesidad','Especialidad médica en Obesidad'),
('Obstetricia','Especialidad médica en Obstetricia'),
('Odontologia','Especialidad médica en Odontologia'),
('Odontopediatria','Especialidad médica en Odontopediatria'),
('Oftalmologia','Especialidad médica en Oftalmologia'),
('Oftalmologia Infantil','Especialidad médica en Oftalmologia Infantil'),
('Oncologia','Especialidad médica en Oncologia'),
('Oncologia Infantil','Especialidad médica en Oncologia Infantil'),
('Ortodoncia','Especialidad médica en Ortodoncia'),
('Ortopedia','Especialidad médica en Ortopedia'),
('Ortopedia Infantil','Especialidad médica en Ortopedia Infantil'),
('Ortopedia Maxilar','Especialidad médica en Ortopedia Maxilar'),
('Osteologia','Especialidad médica en Osteologia'),
('Otorrinolaringologia','Especialidad médica en Otorrinolaringologia'),
('Otorrinolaringologia Infantil','Especialidad médica en Otorrinolaringologia Infantil'),
('Parasitologia','Especialidad médica en Parasitologia'),
('Pediatria','Especialidad médica en Pediatria'),
('Perinatologia','Especialidad médica en Perinatologia'),
('Periodoncia','Especialidad médica en Periodoncia'),
('Protesis Dentobucomaxilar','Especialidad médica en Protesis Dentobucomaxilar'),
('Psicologia Clinica','Especialidad médica en Psicologia Clinica'),
('Psicologia Educacional','Especialidad médica en Psicologia Educacional'),
('Psicologia Juridica','Especialidad médica en Psicologia Juridica'),
('Psicologia Laboral','Especialidad médica en Psicologia Laboral'),
('Psicologia Sanitaria','Especialidad médica en Psicologia Sanitaria'),
('Psicologia Social','Especialidad médica en Psicologia Social'),
('Psiquiatria','Especialidad médica en Psiquiatria'),
('Psiquiatria Infanto Juvenil','Especialidad médica en Psiquiatria Infanto Juvenil'),
('Radiologia','Especialidad médica en Radiologia'),
('Radioterapia','Especialidad médica en Radioterapia'),
('Reproduccion','Especialidad médica en Reproduccion'),
('Reumatologia','Especialidad médica en Reumatologia'),
('Tocoginecologia','Especialidad médica en Tocoginecologia'),
('Toxicologia','Especialidad médica en Toxicologia'),
('Traumatologia Infantil','Especialidad médica en Traumatologia Infantil'),
('Traumatologia Maxilo Facial','Especialidad médica en Traumatologia Maxilo Facial'),
('Traumatologia Y Ortopedia','Especialidad médica en Traumatologia Y Ortopedia'),
('Urologia','Especialidad médica en Urologia'),
('Urologia Infantil','Especialidad médica en Urologia Infantil'),
('Varios / Otros','Especialidad médica en Varios / Otros');
-- Insertar médicos de familia
INSERT INTO myhealth.familydoctor(professionalnumber, password, nif, surname, email, name, primaryhealthcarecenterid) VALUES
('PRO#100','912EC803B2CE49E4A541068D495AB570','95874388S','Moran Ortiz', 'Xian@example.ecom','Xian', 1)
,('PRO#101','912EC803B2CE49E4A541068D495AB570','59546140Z','Zambrano Rivas', 'Belen@example.ecom','Belen', 2)
,('PRO#102','912EC803B2CE49E4A541068D495AB570','16354100L','Cuevas Luque', 'Fernando@example.ecom','Fernando', 3)
,('PRO#103','912EC803B2CE49E4A541068D495AB570','32662259M','Becerra Muñiz', 'Luis@example.ecom','Luis', 4)
,('PRO#104','912EC803B2CE49E4A541068D495AB570','70600712G','Aznar Silva', 'Ana@example.ecom','Ana', 5)
,('PRO#105','912EC803B2CE49E4A541068D495AB570','08003806J','Galvez Sancho', 'Alfonso@example.ecom','Alfonso', 6)
,('PRO#106','912EC803B2CE49E4A541068D495AB570','19567288S','Criado Marti', 'Jordi@example.ecom','Jordi', 7)
,('PRO#107','912EC803B2CE49E4A541068D495AB570','95413653Q','Estevez Mena', 'Barbara@example.ecom','Barbara', 8)
,('PRO#108','912EC803B2CE49E4A541068D495AB570','90914444K','Godoy Alcaide', 'Amalia@example.ecom','Amalia', 9)
,('PRO#109','912EC803B2CE49E4A541068D495AB570','05709869G','Lucas Wang', 'Carmelo@example.ecom','Carmelo', 10);
('PRO#100','912EC803B2CE49E4A541068D495AB570','95874388S','Moran Ortiz', 'Xian@example.com','Xian', 1),
('PRO#101','912EC803B2CE49E4A541068D495AB570','59546140Z','Zambrano Rivas', 'Belen@example.com','Belen', 2),
('PRO#102','912EC803B2CE49E4A541068D495AB570','16354100L','Cuevas Luque', 'Fernando@example.com','Fernando', 3),
('PRO#103','912EC803B2CE49E4A541068D495AB570','32662259M','Becerra Muñiz', 'Luis@example.com','Luis', 4),
('PRO#104','912EC803B2CE49E4A541068D495AB570','70600712G','Aznar Silva', 'Ana@example.com','Ana', 5),
('PRO#105','912EC803B2CE49E4A541068D495AB570','08003806J','Galvez Sancho', 'Alfonso@example.com','Alfonso', 6),
('PRO#106','912EC803B2CE49E4A541068D495AB570','19567288S','Criado Marti', 'Jordi@example.com','Jordi', 7),
('PRO#107','912EC803B2CE49E4A541068D495AB570','95413653Q','Estevez Mena', 'Barbara@example.com','Barbara', 8),
('PRO#108','912EC803B2CE49E4A541068D495AB570','90914444K','Godoy Alcaide', 'Amalia@example.com','Amalia', 9),
('PRO#109','912EC803B2CE49E4A541068D495AB570','05709869G','Lucas Wang', 'Carmelo@example.com','Carmelo', 10),
('PRO#321','912EC803B2CE49E4A541068D495AB570','83450147Y','Zambrano Gonzalez', 'Teodoro@example.com',' Teodoro', 1),
('PRO#322','912EC803B2CE49E4A541068D495AB570','82460286L','Melero Vaquero', 'Manuel Jose@example.com',' Manuel Jose', 2),
('PRO#323','912EC803B2CE49E4A541068D495AB570','66027106V','Amaya Juarez', 'Gustavo@example.com',' Gustavo', 3),
('PRO#324','912EC803B2CE49E4A541068D495AB570','35535426N','Santos Carmona', 'Gemma@example.com',' Gemma', 4),
('PRO#325','912EC803B2CE49E4A541068D495AB570','03169193T','Lin Gracia', 'Ramiro@example.com',' Ramiro', 5),
('PRO#326','912EC803B2CE49E4A541068D495AB570','65718014E','Pacheco Gonzalo', 'Maria Yolanda@example.com',' Maria Yolanda', 6),
('PRO#327','912EC803B2CE49E4A541068D495AB570','29571200P','Calero Duarte', 'Rosalia@example.com',' Rosalia', 7),
('PRO#328','912EC803B2CE49E4A541068D495AB570','73755195Z','Andres Ros', 'Jessica@example.com',' Jessica', 8),
('PRO#329','912EC803B2CE49E4A541068D495AB570','71593467X','Sanz Palomo', 'Adolfo@example.com',' Adolfo', 9),
('PRO#330','912EC803B2CE49E4A541068D495AB570','85689934F','Cabello Molina', 'Mar@example.com',' Mar', 10),
('PRO#331','912EC803B2CE49E4A541068D495AB570','05118688S','Domingo Diez', 'Felicidad@example.com',' Felicidad', 11),
('PRO#332','912EC803B2CE49E4A541068D495AB570','59057948C','Fernandez Medina', 'Amador@example.com',' Amador', 12),
('PRO#333','912EC803B2CE49E4A541068D495AB570','84861480J','De La Torre Arranz', 'Magdalena@example.com',' Magdalena', 13),
('PRO#334','912EC803B2CE49E4A541068D495AB570','77743570M','Mohamed Carmona', 'Oscar@example.com',' Oscar', 14),
('PRO#335','912EC803B2CE49E4A541068D495AB570','86346483K','Camacho Valle', 'Julio@example.com',' Julio', 15),
('PRO#336','912EC803B2CE49E4A541068D495AB570','56743696M','Gimenez Bartolome', 'Maria Asuncion@example.com',' Maria Asuncion', 16),
('PRO#337','912EC803B2CE49E4A541068D495AB570','67594210Q','Carbonell Piñeiro', 'Almudena@example.com',' Almudena', 1),
('PRO#338','912EC803B2CE49E4A541068D495AB570','32394018J','Bonet Bermejo', 'Marcelino@example.com',' Marcelino', 2),
('PRO#339','912EC803B2CE49E4A541068D495AB570','93248168G','Carrera Ortiz', 'Alexandre@example.com',' Alexandre', 3),
('PRO#340','912EC803B2CE49E4A541068D495AB570','45633960M','Crespo Abad', 'Santos@example.com',' Santos', 4),
('PRO#341','912EC803B2CE49E4A541068D495AB570','44975754J','Ocaña Medina', 'Ines@example.com',' Ines', 5),
('PRO#342','912EC803B2CE49E4A541068D495AB570','66498632C','Suarez Recio', 'Pedro@example.com',' Pedro', 6),
('PRO#343','912EC803B2CE49E4A541068D495AB570','83283712E','Saenz Carballo', 'Roser@example.com',' Roser', 7),
('PRO#344','912EC803B2CE49E4A541068D495AB570','22460230V','Menendez Alcantara', 'Carlos Alberto@example.com',' Carlos Alberto', 8),
('PRO#345','912EC803B2CE49E4A541068D495AB570','40900569Z','Jurado Carrion', 'Moises@example.com',' Moises', 9),
('PRO#346','912EC803B2CE49E4A541068D495AB570','47264240E','Alvarez Blasco', 'Adrian@example.com',' Adrian', 10),
('PRO#347','912EC803B2CE49E4A541068D495AB570','74061660G','Brito Molina', 'Jesus@example.com',' Jesus', 11),
('PRO#348','912EC803B2CE49E4A541068D495AB570','07432923J','Miralles Leal', 'Hector@example.com',' Hector', 12),
('PRO#349','912EC803B2CE49E4A541068D495AB570','56260234A','Chamorro Heras', 'Erik@example.com',' Erik', 13),
('PRO#350','912EC803B2CE49E4A541068D495AB570','37425385S','Arevalo Iglesias', 'Cristian@example.com',' Cristian', 14),
('PRO#351','912EC803B2CE49E4A541068D495AB570','38629626E','Polo Moral', 'Ivan@example.com',' Ivan', 15),
('PRO#352','912EC803B2CE49E4A541068D495AB570','40325942L','Pozo Gonzalez', 'Gregorio@example.com',' Gregorio', 16),
('PRO#353','912EC803B2CE49E4A541068D495AB570','48070502L','Salas Lozano', 'Elsa@example.com',' Elsa', 1),
('PRO#354','912EC803B2CE49E4A541068D495AB570','22743402J','Rosado Toledo', 'Carolina@example.com',' Carolina', 2),
('PRO#355','912EC803B2CE49E4A541068D495AB570','99704244A','Salazar Conde', 'Luis Angel@example.com',' Luis Angel', 3),
('PRO#356','912EC803B2CE49E4A541068D495AB570','31213766Y','Prado Maldonado', 'Pere@example.com',' Pere', 4),
('PRO#357','912EC803B2CE49E4A541068D495AB570','97558390A','Lin Poveda', 'Isidoro@example.com',' Isidoro', 5),
('PRO#358','912EC803B2CE49E4A541068D495AB570','20032738Z','Cuadrado Costa', 'Claudia@example.com',' Claudia', 6),
('PRO#359','912EC803B2CE49E4A541068D495AB570','01694490B','Melero Castellanos', 'Enric@example.com',' Enric', 7),
('PRO#360','912EC803B2CE49E4A541068D495AB570','59261456R','Domenech Gamez', 'Adriana@example.com',' Adriana', 8),
('PRO#361','912EC803B2CE49E4A541068D495AB570','26604091Z','Domingo Singh', 'Luis Antonio@example.com',' Luis Antonio', 9),
('PRO#362','912EC803B2CE49E4A541068D495AB570','81656673A','Sastre Frias', 'Candido@example.com',' Candido', 10),
('PRO#363','912EC803B2CE49E4A541068D495AB570','29212812Y','Palma Mohamed', 'Pilar@example.com',' Pilar', 11),
('PRO#364','912EC803B2CE49E4A541068D495AB570','95125089X','Pino Aguilar', 'Adolfo@example.com',' Adolfo', 12),
('PRO#365','912EC803B2CE49E4A541068D495AB570','38877119N','Martinez Galvan', 'Jimena@example.com',' Jimena', 13),
('PRO#366','912EC803B2CE49E4A541068D495AB570','40405748S','Sola Bermejo', 'Eloy@example.com',' Eloy', 14),
('PRO#367','912EC803B2CE49E4A541068D495AB570','27910288H','Fuentes Lorenzo', 'Maria Consuelo@example.com',' Maria Consuelo', 15),
('PRO#368','912EC803B2CE49E4A541068D495AB570','51584830Q','Aragon Royo', 'Ruth@example.com',' Ruth', 16),
('PRO#369','912EC803B2CE49E4A541068D495AB570','06962730D','Alcalde Velez', 'Rafaela@example.com',' Rafaela', 1),
('PRO#370','912EC803B2CE49E4A541068D495AB570','80990695J','Bermejo Blasco', 'Cristian@example.com',' Cristian', 2),
('PRO#371','912EC803B2CE49E4A541068D495AB570','16082754G','Guerrero Santiago', 'Carla@example.com',' Carla', 3),
('PRO#372','912EC803B2CE49E4A541068D495AB570','21789241F','Acosta Trujillo', 'Antonio Jesus@example.com',' Antonio Jesus', 4),
('PRO#373','912EC803B2CE49E4A541068D495AB570','21110391W','Villar Bonet', 'Abraham@example.com',' Abraham', 5),
('PRO#374','912EC803B2CE49E4A541068D495AB570','71926018G','Caceres Aznar', 'Africa@example.com',' Africa', 6),
('PRO#375','912EC803B2CE49E4A541068D495AB570','02983300Q','Estevez Marrero', 'Pablo@example.com',' Pablo', 7),
('PRO#376','912EC803B2CE49E4A541068D495AB570','79922817W','Carrion Delgado', 'Alba@example.com',' Alba', 8),
('PRO#377','912EC803B2CE49E4A541068D495AB570','63817139M','Miguel Wang', 'Cesar@example.com',' Cesar', 9),
('PRO#378','912EC803B2CE49E4A541068D495AB570','26667496P','Serna Godoy', 'Rafael@example.com',' Rafael', 10),
('PRO#379','912EC803B2CE49E4A541068D495AB570','34667199N','Iglesias Mateo', 'Carmen Maria@example.com',' Carmen Maria', 11),
('PRO#380','912EC803B2CE49E4A541068D495AB570','97436006W','Chacon Mohamed', 'Isidro@example.com',' Isidro', 12),
('PRO#381','912EC803B2CE49E4A541068D495AB570','72203762T','Cordero Olivares', 'Ramon@example.com',' Ramon', 13),
('PRO#382','912EC803B2CE49E4A541068D495AB570','33218652M','Padilla Casas', 'Soledad@example.com',' Soledad', 14),
('PRO#383','912EC803B2CE49E4A541068D495AB570','75011128D','Jimenez Burgos', 'Mohammed@example.com',' Mohammed', 15),
('PRO#384','912EC803B2CE49E4A541068D495AB570','31299876G','Figueroa Naranjo', 'Ana Belen@example.com',' Ana Belen', 16),
('PRO#385','912EC803B2CE49E4A541068D495AB570','57748477P','Vidal Roldan', 'Josefina@example.com',' Josefina', 1),
('PRO#386','912EC803B2CE49E4A541068D495AB570','99198742H','Rosa Andres', 'Aurora@example.com',' Aurora', 2),
('PRO#387','912EC803B2CE49E4A541068D495AB570','65340851J','Castellanos Vergara', 'Juan Jesus@example.com',' Juan Jesus', 3),
('PRO#388','912EC803B2CE49E4A541068D495AB570','67858714C','Alcaraz Solano', 'Emilio Jose@example.com',' Emilio Jose', 4),
('PRO#389','912EC803B2CE49E4A541068D495AB570','34364420M','Huerta Rico', 'Noemi@example.com',' Noemi', 5),
('PRO#390','912EC803B2CE49E4A541068D495AB570','47372815Z','Soto Calvo', 'Nicolas@example.com',' Nicolas', 6),
('PRO#391','912EC803B2CE49E4A541068D495AB570','81695922Z','Saenz Arevalo', 'Ana Rosa@example.com',' Ana Rosa', 7),
('PRO#392','912EC803B2CE49E4A541068D495AB570','20870549G','Navarrete Villalba', 'Natividad@example.com',' Natividad', 8),
('PRO#393','912EC803B2CE49E4A541068D495AB570','30140343Q','Gracia Galindo', 'Matias@example.com',' Matias', 9),
('PRO#394','912EC803B2CE49E4A541068D495AB570','57107502C','Piñero Correa', 'Rosario@example.com',' Rosario', 10),
('PRO#395','912EC803B2CE49E4A541068D495AB570','31599091N','Clemente Frias', 'Susana@example.com',' Susana', 11),
('PRO#396','912EC803B2CE49E4A541068D495AB570','78191056A','Miguel Aguirre', 'Sergio@example.com',' Sergio', 12),
('PRO#397','912EC803B2CE49E4A541068D495AB570','94696539L','Vazquez Toro', 'Mohamed@example.com',' Mohamed', 13),
('PRO#398','912EC803B2CE49E4A541068D495AB570','74130059R','Ojeda Blasco', 'Francisco Javier@example.com',' Francisco Javier', 14),
('PRO#399','912EC803B2CE49E4A541068D495AB570','54263073R','Calleja Flores', 'Teodoro@example.com',' Teodoro', 15),
('PRO#400','912EC803B2CE49E4A541068D495AB570','64905450W','Martinez Olmedo', 'Eloisa@example.com',' Eloisa', 16),
('PRO#401','912EC803B2CE49E4A541068D495AB570','04669076F','Blasco Melero', 'Leonor@example.com',' Leonor', 1),
('PRO#402','912EC803B2CE49E4A541068D495AB570','53157751J','Freire Ferrer', 'Ana Isabel@example.com',' Ana Isabel', 2),
('PRO#403','912EC803B2CE49E4A541068D495AB570','84275316G','Figueroa Salgado', 'Ricardo@example.com',' Ricardo', 3),
('PRO#404','912EC803B2CE49E4A541068D495AB570','47424325G','Rebollo Pineda', 'Gerardo@example.com',' Gerardo', 4),
('PRO#405','912EC803B2CE49E4A541068D495AB570','53099713G','Martinez Solis', 'Maria Purificacion@example.com',' Maria Purificacion', 5),
('PRO#406','912EC803B2CE49E4A541068D495AB570','09794229R','Flores Guijarro', 'Israel@example.com',' Israel', 6),
('PRO#407','912EC803B2CE49E4A541068D495AB570','74409378P','Bosch Zapata', 'Daniel@example.com',' Daniel', 7),
('PRO#408','912EC803B2CE49E4A541068D495AB570','18863538L','Carmona Sastre', 'Margarita@example.com',' Margarita', 8),
('PRO#409','912EC803B2CE49E4A541068D495AB570','66477577X','Rovira Cuevas', 'Jose Carlos@example.com',' Jose Carlos', 9),
('PRO#410','912EC803B2CE49E4A541068D495AB570','35967055T','Aranda Valls', 'Florentina@example.com',' Florentina', 10),
('PRO#411','912EC803B2CE49E4A541068D495AB570','98404637B','Redondo Peinado', 'Joana@example.com',' Joana', 11),
('PRO#412','912EC803B2CE49E4A541068D495AB570','55337416Z','Robles Ramon', 'Bruno@example.com',' Bruno', 12),
('PRO#413','912EC803B2CE49E4A541068D495AB570','39043197F','Campo Asensio', 'Maria Gracia@example.com',' Maria Gracia', 13),
('PRO#414','912EC803B2CE49E4A541068D495AB570','61113485R','Millan Melero', 'Jaime@example.com',' Jaime', 14),
('PRO#415','912EC803B2CE49E4A541068D495AB570','88756716S','Gil Pastor', 'Jan@example.com',' Jan', 15),
('PRO#416','912EC803B2CE49E4A541068D495AB570','61608684X','Del Valle Villa', 'Consolacion@example.com',' Consolacion', 16),
('PRO#417','912EC803B2CE49E4A541068D495AB570','46601056C','Varela Alarcon', 'Felipe@example.com',' Felipe', 1),
('PRO#418','912EC803B2CE49E4A541068D495AB570','80611975B','Vega Molina', 'Roberto@example.com',' Roberto', 2),
('PRO#419','912EC803B2CE49E4A541068D495AB570','95160642M','Calvo Luis', 'Guillermo@example.com',' Guillermo', 3),
('PRO#420','912EC803B2CE49E4A541068D495AB570','88511050N','Caballero Duarte', 'Oliver@example.com',' Oliver', 4),
('PRO#421','912EC803B2CE49E4A541068D495AB570','41289667K','Davila Blanco', 'Albert@example.com',' Albert', 1),
('PRO#422','912EC803B2CE49E4A541068D495AB570','20430184C','Vives Cordero', 'Jose Manuel@example.com',' Jose Manuel', 2),
('PRO#423','912EC803B2CE49E4A541068D495AB570','85921489K','Mateo Rico', 'Carmelo@example.com',' Carmelo', 3),
('PRO#424','912EC803B2CE49E4A541068D495AB570','31634396N','Macias Prieto', 'Jose Antonio@example.com',' Jose Antonio', 4),
('PRO#425','912EC803B2CE49E4A541068D495AB570','53781842E','Lazaro Villegas', 'Maria Purificacion@example.com',' Maria Purificacion', 5),
('PRO#426','912EC803B2CE49E4A541068D495AB570','03396741D','Frias Abad', 'Juan Luis@example.com',' Juan Luis', 6),
('PRO#427','912EC803B2CE49E4A541068D495AB570','30561128Q','Carrasco Luis', 'Gregoria@example.com',' Gregoria', 7),
('PRO#428','912EC803B2CE49E4A541068D495AB570','06994306Y','Mateos Amaya', 'Pedro@example.com',' Pedro', 8),
('PRO#429','912EC803B2CE49E4A541068D495AB570','61950502W','Macias Cuevas', 'Juan Carlos@example.com',' Juan Carlos', 9),
('PRO#430','912EC803B2CE49E4A541068D495AB570','07916216F','Fajardo Rodrigo', 'Josep@example.com',' Josep', 10),
('PRO#431','912EC803B2CE49E4A541068D495AB570','56885913J','Leal Soria', 'Juliana@example.com',' Juliana', 11),
('PRO#432','912EC803B2CE49E4A541068D495AB570','84206156M','Miranda Luque', 'Vicenta@example.com',' Vicenta', 12),
('PRO#433','912EC803B2CE49E4A541068D495AB570','37898942W','Sainz Baena', 'Aroa@example.com',' Aroa', 13),
('PRO#434','912EC803B2CE49E4A541068D495AB570','19268095Y','Fraile Latorre', 'Isabel Maria@example.com',' Isabel Maria', 14),
('PRO#435','912EC803B2CE49E4A541068D495AB570','53006303C','Iglesias Padilla', 'Maria Rosario@example.com',' Maria Rosario', 15),
('PRO#436','912EC803B2CE49E4A541068D495AB570','86009326K','Mendez Alfaro', 'Encarnacion@example.com',' Encarnacion', 16),
('PRO#437','912EC803B2CE49E4A541068D495AB570','76519090E','Sole Calderon', 'Jesus Angel@example.com',' Jesus Angel', 1),
('PRO#438','912EC803B2CE49E4A541068D495AB570','87397882K','Villegas Piñeiro', 'Natalia@example.com',' Natalia', 2),
('PRO#439','912EC803B2CE49E4A541068D495AB570','52855443V','Amaya Vela', 'Maria Nieves@example.com',' Maria Nieves', 3),
('PRO#440','912EC803B2CE49E4A541068D495AB570','96626367D','Sevilla Pena', 'Jaume@example.com',' Jaume', 4),
('PRO#441','912EC803B2CE49E4A541068D495AB570','08466139T','Bernal Palacios', 'Juan Jesus@example.com',' Juan Jesus', 5),
('PRO#442','912EC803B2CE49E4A541068D495AB570','89892351W','Coll Calleja', 'Natalia@example.com',' Natalia', 6),
('PRO#443','912EC803B2CE49E4A541068D495AB570','41130356P','Jorge Salvador', 'Gines@example.com',' Gines', 7),
('PRO#444','912EC803B2CE49E4A541068D495AB570','65624256N','Amaya Prado', 'Eric@example.com',' Eric', 8),
('PRO#445','912EC803B2CE49E4A541068D495AB570','25492168A','Toro Lozano', 'Sebastian@example.com',' Sebastian', 9),
('PRO#446','912EC803B2CE49E4A541068D495AB570','00150656Y','Campos Araujo', 'Armando@example.com',' Armando', 10),
('PRO#447','912EC803B2CE49E4A541068D495AB570','98059584G','Alcala Sala', 'Gemma@example.com',' Gemma', 11),
('PRO#448','912EC803B2CE49E4A541068D495AB570','97579373X','Polo Corrales', 'Jacobo@example.com',' Jacobo', 12),
('PRO#449','912EC803B2CE49E4A541068D495AB570','69669161E','Merino Vicente', 'Antonio Miguel@example.com',' Antonio Miguel', 13),
('PRO#450','912EC803B2CE49E4A541068D495AB570','86338060Q','Borrego Carballo', 'Sheila@example.com',' Sheila', 14),
('PRO#451','912EC803B2CE49E4A541068D495AB570','62730348X','Pineda Rosado', 'Eulalia@example.com',' Eulalia', 15),
('PRO#452','912EC803B2CE49E4A541068D495AB570','80566269Y','Estevez Izquierdo', 'Victoriano@example.com',' Victoriano', 16),
('PRO#453','912EC803B2CE49E4A541068D495AB570','78274293A','Cuenca Lorente', 'Isaac@example.com',' Isaac', 1),
('PRO#454','912EC803B2CE49E4A541068D495AB570','73356975Q','Rovira Calero', 'Tamara@example.com',' Tamara', 2),
('PRO#455','912EC803B2CE49E4A541068D495AB570','79912367V','Mena Bravo', 'Adela@example.com',' Adela', 3),
('PRO#456','912EC803B2CE49E4A541068D495AB570','06382429K','Barragan Sanchez', 'Pedro Manuel@example.com',' Pedro Manuel', 4),
('PRO#457','912EC803B2CE49E4A541068D495AB570','37448458L','Carrion Palomo', 'Alicia@example.com',' Alicia', 1),
('PRO#458','912EC803B2CE49E4A541068D495AB570','75923674F','Rodrigo Ramos', 'Paula@example.com',' Paula', 2),
('PRO#459','912EC803B2CE49E4A541068D495AB570','74322757M','Estevez Ventura', 'Gloria@example.com',' Gloria', 3),
('PRO#460','912EC803B2CE49E4A541068D495AB570','49838470T','Galvez Amaya', 'Manuel@example.com',' Manuel', 4),
('PRO#461','912EC803B2CE49E4A541068D495AB570','63831045L','Pujol Oliver', 'Sheila@example.com',' Sheila', 5),
('PRO#462','912EC803B2CE49E4A541068D495AB570','18375822H','Corral Ruano', 'Maria Esperanza@example.com',' Maria Esperanza', 6),
('PRO#463','912EC803B2CE49E4A541068D495AB570','73127729B','Iglesias Lobato', 'Enriqueta@example.com',' Enriqueta', 7),
('PRO#464','912EC803B2CE49E4A541068D495AB570','93813178L','Lin Cabrera', 'Nerea@example.com',' Nerea', 8),
('PRO#465','912EC803B2CE49E4A541068D495AB570','49476995Q','Barbero Mateu', 'Matias@example.com',' Matias', 9),
('PRO#466','912EC803B2CE49E4A541068D495AB570','46787648J','Dorado Luna', 'Juan Jesus@example.com',' Juan Jesus', 10),
('PRO#467','912EC803B2CE49E4A541068D495AB570','17059489K','Pacheco Solano', 'Isabel@example.com',' Isabel', 11),
('PRO#468','912EC803B2CE49E4A541068D495AB570','68753335X','Jurado Herranz', 'Victoriano@example.com',' Victoriano', 12),
('PRO#469','912EC803B2CE49E4A541068D495AB570','56146157Y','Sanchez Marco', 'Julio@example.com',' Julio', 13),
('PRO#470','912EC803B2CE49E4A541068D495AB570','28895880Z','Ferrero Bermudez', 'Noelia@example.com',' Noelia', 14),
('PRO#471','912EC803B2CE49E4A541068D495AB570','95804647X','Morillo Valero', 'Trinidad@example.com',' Trinidad', 15),
('PRO#472','912EC803B2CE49E4A541068D495AB570','01548835S','Carrion Arranz', 'Itziar@example.com',' Itziar', 16),
('PRO#473','912EC803B2CE49E4A541068D495AB570','11620234J','Caballero Arranz', 'Maite@example.com',' Maite', 1),
('PRO#474','912EC803B2CE49E4A541068D495AB570','01205009Q','Gracia Carrion', 'Alfredo@example.com',' Alfredo', 2),
('PRO#475','912EC803B2CE49E4A541068D495AB570','19652249Z','Suarez Muñiz', 'Avelino@example.com',' Avelino', 3),
('PRO#476','912EC803B2CE49E4A541068D495AB570','36983526D','Gimenez Romera', 'Margarita@example.com',' Margarita', 4),
('PRO#477','912EC803B2CE49E4A541068D495AB570','13116881G','Guerra Aviles', 'Susana@example.com',' Susana', 5),
('PRO#478','912EC803B2CE49E4A541068D495AB570','00743418N','Ortiz Pizarro', 'Ricardo@example.com',' Ricardo', 6),
('PRO#479','912EC803B2CE49E4A541068D495AB570','49532302P','Pereira Leon', 'Diana@example.com',' Diana', 7),
('PRO#480','912EC803B2CE49E4A541068D495AB570','29019974T','Barrera Gomez', 'Candido@example.com',' Candido', 8),
('PRO#481','912EC803B2CE49E4A541068D495AB570','54059624X','Aznar Rico', 'Maria Eugenia@example.com',' Maria Eugenia', 9),
('PRO#482','912EC803B2CE49E4A541068D495AB570','50099259S','Ocaña Salas', 'Adelaida@example.com',' Adelaida', 10),
('PRO#483','912EC803B2CE49E4A541068D495AB570','10034450X','Cid Calvo', 'Roger@example.com',' Roger', 11),
('PRO#484','912EC803B2CE49E4A541068D495AB570','39781057G','Silva Piñero', 'Maria Luisa@example.com',' Maria Luisa', 12),
('PRO#485','912EC803B2CE49E4A541068D495AB570','30250717J','Pinto Anton', 'Fatima@example.com',' Fatima', 13),
('PRO#486','912EC803B2CE49E4A541068D495AB570','54326793B','Escudero Guerra', 'Jose Andres@example.com',' Jose Andres', 14),
('PRO#487','912EC803B2CE49E4A541068D495AB570','12077553T','Marin Portillo', 'Ignacio@example.com',' Ignacio', 15),
('PRO#488','912EC803B2CE49E4A541068D495AB570','81173756V','Singh Agudo', 'Emiliano@example.com',' Emiliano', 16),
('PRO#489','912EC803B2CE49E4A541068D495AB570','18965821K','Cobos Merino', 'Eloy@example.com',' Eloy', 1),
('PRO#490','912EC803B2CE49E4A541068D495AB570','90888158R','Heras Pulido', 'Manuel Antonio@example.com',' Manuel Antonio', 2),
('PRO#491','912EC803B2CE49E4A541068D495AB570','10769780F','Exposito Riera', 'Aleix@example.com',' Aleix', 3),
('PRO#492','912EC803B2CE49E4A541068D495AB570','50993180H','Becerra Abad', 'Felisa@example.com',' Felisa', 4),
('PRO#493','912EC803B2CE49E4A541068D495AB570','60112400Z','Criado Pizarro', 'Rocio@example.com',' Rocio', 1),
('PRO#494','912EC803B2CE49E4A541068D495AB570','24121440Y','Tapia Aznar', 'Maria Begoña@example.com',' Maria Begoña', 2),
('PRO#495','912EC803B2CE49E4A541068D495AB570','14182618J','Rojas Ferrero', 'Daniel@example.com',' Daniel', 3),
('PRO#496','912EC803B2CE49E4A541068D495AB570','51057632R','Linares Marcos', 'Jose Andres@example.com',' Jose Andres', 4),
('PRO#497','912EC803B2CE49E4A541068D495AB570','74414073B','Rueda Caceres', 'Isaac@example.com',' Isaac', 5),
('PRO#498','912EC803B2CE49E4A541068D495AB570','33474231P','Guerrero Rosa', 'Ruth@example.com',' Ruth', 6),
('PRO#499','912EC803B2CE49E4A541068D495AB570','33127256B','Corrales Palacios', 'Irene@example.com',' Irene', 7),
('PRO#500','912EC803B2CE49E4A541068D495AB570','35105963M','Guzman Pinto', 'Aina@example.com',' Aina', 8),
('PRO#501','912EC803B2CE49E4A541068D495AB570','26500674M','Catalan Wang', 'Alexandre@example.com',' Alexandre', 9),
('PRO#502','912EC803B2CE49E4A541068D495AB570','68092329R','Lago Arce', 'Maria Cruz@example.com',' Maria Cruz', 10),
('PRO#503','912EC803B2CE49E4A541068D495AB570','79438264J','Casanova Gracia', 'Jose Javier@example.com',' Jose Javier', 11),
('PRO#504','912EC803B2CE49E4A541068D495AB570','09814614P','Velazquez Brito', 'Fidel@example.com',' Fidel', 12),
('PRO#505','912EC803B2CE49E4A541068D495AB570','32685364H','Pavon Peña', 'Eloy@example.com',' Eloy', 13),
('PRO#506','912EC803B2CE49E4A541068D495AB570','27256245A','De Miguel Mateos', 'Ali@example.com',' Ali', 14),
('PRO#507','912EC803B2CE49E4A541068D495AB570','94699844N','Cebrian Rodriguez', 'Marco@example.com',' Marco', 15),
('PRO#508','912EC803B2CE49E4A541068D495AB570','41767128W','Ros Recio', 'Marco@example.com',' Marco', 16),
('PRO#509','912EC803B2CE49E4A541068D495AB570','77614691H','Moya Mata', 'Felipe@example.com',' Felipe', 1),
('PRO#510','912EC803B2CE49E4A541068D495AB570','71675632L','Bonilla Lago', 'Mariana@example.com',' Mariana', 2),
('PRO#511','912EC803B2CE49E4A541068D495AB570','76463200E','Real Hernando', 'Simon@example.com',' Simon', 3),
('PRO#512','912EC803B2CE49E4A541068D495AB570','56824919S','Cabezas Brito', 'Gabriela@example.com',' Gabriela', 4),
('PRO#513','912EC803B2CE49E4A541068D495AB570','41512704G','Rueda Izquierdo', 'Alex@example.com',' Alex', 5),
('PRO#514','912EC803B2CE49E4A541068D495AB570','28007231Q','Menendez Bermejo', 'Carolina@example.com',' Carolina', 6),
('PRO#515','912EC803B2CE49E4A541068D495AB570','99792430F','Beltran Caro', 'Joel@example.com',' Joel', 7),
('PRO#516','912EC803B2CE49E4A541068D495AB570','32636037A','Mateu Roman', 'Inmaculada@example.com',' Inmaculada', 8),
('PRO#517','912EC803B2CE49E4A541068D495AB570','00051095N','Mohamed Linares', 'Angel@example.com',' Angel', 9),
('PRO#518','912EC803B2CE49E4A541068D495AB570','34352497L','Fernandez Exposito', 'Judit@example.com',' Judit', 10),
('PRO#519','912EC803B2CE49E4A541068D495AB570','91654122L','Sanchez Rivas', 'Saray@example.com',' Saray', 11),
('PRO#520','912EC803B2CE49E4A541068D495AB570','56772751B','Gomez Galan', 'Maria Eugenia@example.com',' Maria Eugenia', 12);
-- Insertar médicos especialistas
INSERT INTO myhealth.specialistdoctor(professionalnumber, password, nif, surname, email, name, medicalspecialtyid) VALUES
('PRO#110','912EC803B2CE49E4A541068D495AB570','87719252N','Vazquez Cruz', 'Luciano@example.ecom','Luciano', 1)
,('PRO#111','912EC803B2CE49E4A541068D495AB570','79412306E','Alcaide Mesa', 'Gregorio@example.ecom','Gregorio', 2)
,('PRO#112','912EC803B2CE49E4A541068D495AB570','45727688P','Herranz Soria', 'Candida@example.ecom','Candida', 3)
,('PRO#113','912EC803B2CE49E4A541068D495AB570','65061962E','Galvez Vives', 'Nora@example.ecom','Nora', 4)
,('PRO#114','912EC803B2CE49E4A541068D495AB570','07359870P','Rojas Alonso', 'Anton@example.ecom','Anton', 5)
,('PRO#115','912EC803B2CE49E4A541068D495AB570','14117403A','Lorente Carmona', 'Sheila@example.ecom','Sheila', 6)
,('PRO#116','912EC803B2CE49E4A541068D495AB570','79864477J','Gonzalo Bonet', 'Nicolas@example.ecom','Nicolas', 7)
,('PRO#117','912EC803B2CE49E4A541068D495AB570','22761129F','Bonet Ariza', 'Aroa@example.ecom','Aroa', 8)
,('PRO#118','912EC803B2CE49E4A541068D495AB570','99693813Z','Soria Singh', 'Cristian@example.ecom','Cristian', 9)
,('PRO#119','912EC803B2CE49E4A541068D495AB570','04431824T','Requena Calderon', 'Ferran@example.ecom','Ferran', 10)
,('PRO#120','912EC803B2CE49E4A541068D495AB570','27476123R','Angulo Zamora', 'Ana@example.ecom','Ana', 11);
('PRO#110','912EC803B2CE49E4A541068D495AB570','87719252N','Vazquez Cruz', 'Luciano@example.com','Luciano', 1),
('PRO#111','912EC803B2CE49E4A541068D495AB570','79412306E','Alcaide Mesa', 'Gregorio@example.com','Gregorio', 2),
('PRO#112','912EC803B2CE49E4A541068D495AB570','45727688P','Herranz Soria', 'Candida@example.com','Candida', 3),
('PRO#113','912EC803B2CE49E4A541068D495AB570','65061962E','Galvez Vives', 'Nora@example.com','Nora', 4),
('PRO#114','912EC803B2CE49E4A541068D495AB570','07359870P','Rojas Alonso', 'Anton@example.com','Anton', 5),
('PRO#115','912EC803B2CE49E4A541068D495AB570','14117403A','Lorente Carmona', 'Sheila@example.com','Sheila', 6),
('PRO#116','912EC803B2CE49E4A541068D495AB570','79864477J','Gonzalo Bonet', 'Nicolas@example.com','Nicolas', 7),
('PRO#117','912EC803B2CE49E4A541068D495AB570','22761129F','Bonet Ariza', 'Aroa@example.com','Aroa', 8),
('PRO#118','912EC803B2CE49E4A541068D495AB570','99693813Z','Soria Singh', 'Cristian@example.com','Cristian', 9),
('PRO#119','912EC803B2CE49E4A541068D495AB570','04431824T','Requena Calderon', 'Ferran@example.com','Ferran', 10),
('PRO#120','912EC803B2CE49E4A541068D495AB570','27476123R','Angulo Zamora', 'Ana@example.com','Ana', 11),
('PRO#121','912EC803B2CE49E4A541068D495AB570','63200346A','Chen Collado', 'Manuel@example.com',' Manuel', 1),
('PRO#122','912EC803B2CE49E4A541068D495AB570','87556441H','Font Bonilla', 'Florencio@example.com',' Florencio', 2),
('PRO#123','912EC803B2CE49E4A541068D495AB570','62522538M','Calderon Sole', 'Gorka@example.com',' Gorka', 3),
('PRO#124','912EC803B2CE49E4A541068D495AB570','52266613X','Peña Bello', 'Lucas@example.com',' Lucas', 4),
('PRO#125','912EC803B2CE49E4A541068D495AB570','35226066W','Baena Franco', 'Jose Enrique@example.com',' Jose Enrique', 5),
('PRO#126','912EC803B2CE49E4A541068D495AB570','05411704B','Baena Huerta', 'Noelia@example.com',' Noelia', 6),
('PRO#127','912EC803B2CE49E4A541068D495AB570','70639052A','Galvan Riera', 'Maria Nieves@example.com',' Maria Nieves', 7),
('PRO#128','912EC803B2CE49E4A541068D495AB570','51441755R','Alcaide Rubio', 'Juan@example.com',' Juan', 8),
('PRO#129','912EC803B2CE49E4A541068D495AB570','46690797S','Crespo Hidalgo', 'Esther@example.com',' Esther', 9),
('PRO#130','912EC803B2CE49E4A541068D495AB570','51872299P','Arenas Arce', 'Armando@example.com',' Armando', 10),
('PRO#131','912EC803B2CE49E4A541068D495AB570','80243349Y','Otero Pineda', 'Jorge@example.com',' Jorge', 11),
('PRO#132','912EC803B2CE49E4A541068D495AB570','36255263H','Calero Vargas', 'Ramon@example.com',' Ramon', 12),
('PRO#133','912EC803B2CE49E4A541068D495AB570','01524357D','Espinosa Burgos', 'Sheila@example.com',' Sheila', 13),
('PRO#134','912EC803B2CE49E4A541068D495AB570','81172042M','Aparicio Herranz', 'Iris@example.com',' Iris', 14),
('PRO#135','912EC803B2CE49E4A541068D495AB570','37020368M','Toro Rosales', 'Iria@example.com',' Iria', 15),
('PRO#136','912EC803B2CE49E4A541068D495AB570','09345033H','Paz Saenz', 'Gonzalo@example.com',' Gonzalo', 1),
('PRO#137','912EC803B2CE49E4A541068D495AB570','32994133N','Borrego Vaquero', 'Rafaela@example.com',' Rafaela', 2),
('PRO#138','912EC803B2CE49E4A541068D495AB570','43792071W','Bravo Escobar', 'Jose Antonio@example.com',' Jose Antonio', 3),
('PRO#139','912EC803B2CE49E4A541068D495AB570','07487280K','Hidalgo Pino', 'Marc@example.com',' Marc', 4),
('PRO#140','912EC803B2CE49E4A541068D495AB570','41863652H','Pardo Carrasco', 'Maria Concepcion@example.com',' Maria Concepcion', 5),
('PRO#141','912EC803B2CE49E4A541068D495AB570','41825932H','Santos Peinado', 'Maria Teresa@example.com',' Maria Teresa', 6),
('PRO#142','912EC803B2CE49E4A541068D495AB570','17982798H','Nieto Barbero', 'Vicenta@example.com',' Vicenta', 7),
('PRO#143','912EC803B2CE49E4A541068D495AB570','57918141R','Carretero Guzman', 'Erika@example.com',' Erika', 8),
('PRO#144','912EC803B2CE49E4A541068D495AB570','03218286B','Guerrero Soler', 'Maria Ines@example.com',' Maria Ines', 9),
('PRO#145','912EC803B2CE49E4A541068D495AB570','88738850C','Moya Guerrero', 'Leire@example.com',' Leire', 10),
('PRO#146','912EC803B2CE49E4A541068D495AB570','27168645X','Rivas Sierra', 'Maria Gracia@example.com',' Maria Gracia', 11),
('PRO#147','912EC803B2CE49E4A541068D495AB570','03108836H','Mora Valero', 'Roman@example.com',' Roman', 12),
('PRO#148','912EC803B2CE49E4A541068D495AB570','53624378Q','Aranda Santamaria', 'Gerardo@example.com',' Gerardo', 13),
('PRO#149','912EC803B2CE49E4A541068D495AB570','04604817X','Galvez Reyes', 'Pedro Manuel@example.com',' Pedro Manuel', 14),
('PRO#150','912EC803B2CE49E4A541068D495AB570','00874222S','Lopez Singh', 'Francisco Jose@example.com',' Francisco Jose', 15),
('PRO#151','912EC803B2CE49E4A541068D495AB570','97800629Y','Reyes Paez', 'David@example.com',' David', 1),
('PRO#152','912EC803B2CE49E4A541068D495AB570','41156375Z','Cortes Villanueva', 'Saturnino@example.com',' Saturnino', 2),
('PRO#153','912EC803B2CE49E4A541068D495AB570','91743683H','Calvo Saez', 'Rosalia@example.com',' Rosalia', 3),
('PRO#154','912EC803B2CE49E4A541068D495AB570','42067980Z','Miranda Ponce', 'Maria Rocio@example.com',' Maria Rocio', 4),
('PRO#155','912EC803B2CE49E4A541068D495AB570','05369338B','Arias Cordoba', 'Lucas@example.com',' Lucas', 5),
('PRO#156','912EC803B2CE49E4A541068D495AB570','18011368E','Redondo Ruano', 'Begoña@example.com',' Begoña', 6),
('PRO#157','912EC803B2CE49E4A541068D495AB570','92743213Z','Aparicio Tirado', 'Enrique@example.com',' Enrique', 7),
('PRO#158','912EC803B2CE49E4A541068D495AB570','41560984F','Blazquez Redondo', 'Youssef@example.com',' Youssef', 8),
('PRO#159','912EC803B2CE49E4A541068D495AB570','06175319A','Rios Cardona', 'Silvia@example.com',' Silvia', 9),
('PRO#160','912EC803B2CE49E4A541068D495AB570','89653376C','Arranz Moreno', 'Helena@example.com',' Helena', 10),
('PRO#161','912EC803B2CE49E4A541068D495AB570','60664368M','Juan Sainz', 'Omar@example.com',' Omar', 11),
('PRO#162','912EC803B2CE49E4A541068D495AB570','80826204H','Pereira Moreno', 'Benito@example.com',' Benito', 12),
('PRO#163','912EC803B2CE49E4A541068D495AB570','50746877E','Villar Benitez', 'Marina@example.com',' Marina', 13),
('PRO#164','912EC803B2CE49E4A541068D495AB570','21439447C','Casanova Vera', 'Maria Trinidad@example.com',' Maria Trinidad', 14),
('PRO#165','912EC803B2CE49E4A541068D495AB570','01978793B','Soto Nieto', 'Milagros@example.com',' Milagros', 15),
('PRO#166','912EC803B2CE49E4A541068D495AB570','35114906R','Cebrian Figueroa', 'Jose Antonio@example.com',' Jose Antonio', 1),
('PRO#167','912EC803B2CE49E4A541068D495AB570','75877818J','Villalba Dorado', 'Amador@example.com',' Amador', 2),
('PRO#168','912EC803B2CE49E4A541068D495AB570','62527212X','Paredes Cordoba', 'Agustin@example.com',' Agustin', 3),
('PRO#169','912EC803B2CE49E4A541068D495AB570','12223403F','Ayala Macias', 'Antoni@example.com',' Antoni', 4),
('PRO#170','912EC803B2CE49E4A541068D495AB570','67943317Y','Moral Sole', 'Juan Dios@example.com',' Juan Dios', 5),
('PRO#171','912EC803B2CE49E4A541068D495AB570','37206805G','Montes Noguera', 'Amaya@example.com',' Amaya', 6),
('PRO#172','912EC803B2CE49E4A541068D495AB570','41070839S','Conde Carrillo', 'Nora@example.com',' Nora', 7),
('PRO#173','912EC803B2CE49E4A541068D495AB570','27328878W','Bautista Galvez', 'Damian@example.com',' Damian', 8),
('PRO#174','912EC803B2CE49E4A541068D495AB570','11090242X','Campos Conde', 'Patricia@example.com',' Patricia', 9),
('PRO#175','912EC803B2CE49E4A541068D495AB570','37548322V','Lucas Montes', 'Anna Maria@example.com',' Anna Maria', 10),
('PRO#176','912EC803B2CE49E4A541068D495AB570','15456119G','Cardenas Gracia', 'Maria Luisa@example.com',' Maria Luisa', 11),
('PRO#177','912EC803B2CE49E4A541068D495AB570','25218720W','Cruz Zambrano', 'Rachid@example.com',' Rachid', 12),
('PRO#178','912EC803B2CE49E4A541068D495AB570','28575097N','Miranda Jorge', 'Maria Dolores@example.com',' Maria Dolores', 13),
('PRO#179','912EC803B2CE49E4A541068D495AB570','21028420A','Cordoba Font', 'Manuel Angel@example.com',' Manuel Angel', 14),
('PRO#180','912EC803B2CE49E4A541068D495AB570','74795849X','Ayala De La Fuente', 'Luis Angel@example.com',' Luis Angel', 15),
('PRO#181','912EC803B2CE49E4A541068D495AB570','63272575N','Aranda Naranjo', 'German@example.com',' German', 1),
('PRO#182','912EC803B2CE49E4A541068D495AB570','30922946K','Benito Del Valle', 'Maria Trinidad@example.com',' Maria Trinidad', 2),
('PRO#183','912EC803B2CE49E4A541068D495AB570','87799782L','Marco Trujillo', 'Marcos@example.com',' Marcos', 3),
('PRO#184','912EC803B2CE49E4A541068D495AB570','81064235E','Gallardo Vives', 'Joan@example.com',' Joan', 4),
('PRO#185','912EC803B2CE49E4A541068D495AB570','13075638T','Silva Villalba', 'Iris@example.com',' Iris', 5),
('PRO#186','912EC803B2CE49E4A541068D495AB570','75884122S','Robles Peralta', 'Eneko@example.com',' Eneko', 6),
('PRO#187','912EC803B2CE49E4A541068D495AB570','18172203H','Valls Aguirre', 'Aleix@example.com',' Aleix', 7),
('PRO#188','912EC803B2CE49E4A541068D495AB570','67011122R','Abad Aragon', 'Faustino@example.com',' Faustino', 8),
('PRO#189','912EC803B2CE49E4A541068D495AB570','98032077M','Burgos Fraile', 'Ignacio@example.com',' Ignacio', 9),
('PRO#190','912EC803B2CE49E4A541068D495AB570','38067035B','De La Fuente Huertas', 'Armando@example.com',' Armando', 10),
('PRO#191','912EC803B2CE49E4A541068D495AB570','23296019D','Cordero Simon', 'Angel Luis@example.com',' Angel Luis', 11),
('PRO#192','912EC803B2CE49E4A541068D495AB570','30905728F','Lucas Santamaria', 'Ismael@example.com',' Ismael', 12),
('PRO#193','912EC803B2CE49E4A541068D495AB570','17725094Y','Lozano Ortega', 'Rodrigo@example.com',' Rodrigo', 13),
('PRO#194','912EC803B2CE49E4A541068D495AB570','53796497A','Villa Calero', 'Manuel Angel@example.com',' Manuel Angel', 14),
('PRO#195','912EC803B2CE49E4A541068D495AB570','31035585Y','Linares Moran', 'Clara@example.com',' Clara', 15),
('PRO#196','912EC803B2CE49E4A541068D495AB570','87688318J','Galindo Chamorro', 'Ahmed@example.com',' Ahmed', 1),
('PRO#197','912EC803B2CE49E4A541068D495AB570','63224563R','Robles Silva', 'Ander@example.com',' Ander', 2),
('PRO#198','912EC803B2CE49E4A541068D495AB570','21064044T','Del Valle Sierra', 'Nerea@example.com',' Nerea', 3),
('PRO#199','912EC803B2CE49E4A541068D495AB570','28469395H','Carrillo Pazos', 'Juan Pedro@example.com',' Juan Pedro', 4),
('PRO#200','912EC803B2CE49E4A541068D495AB570','23884523N','Davila Cuevas', 'Felicidad@example.com',' Felicidad', 5),
('PRO#201','912EC803B2CE49E4A541068D495AB570','59093084N','Rincon Calleja', 'Luisa@example.com',' Luisa', 6),
('PRO#202','912EC803B2CE49E4A541068D495AB570','24638334K','Romero Espinosa', 'Jose Angel@example.com',' Jose Angel', 7),
('PRO#203','912EC803B2CE49E4A541068D495AB570','87418789K','Casas Martos', 'Gemma@example.com',' Gemma', 8),
('PRO#204','912EC803B2CE49E4A541068D495AB570','68443798F','Carrasco Montoya', 'Lucas@example.com',' Lucas', 9),
('PRO#205','912EC803B2CE49E4A541068D495AB570','97342309F','Dorado Rojas', 'Marta@example.com',' Marta', 10),
('PRO#206','912EC803B2CE49E4A541068D495AB570','39208401W','Romero Ortiz', 'Jaime@example.com',' Jaime', 11),
('PRO#207','912EC803B2CE49E4A541068D495AB570','59129765P','Franco Dorado', 'Valeria@example.com',' Valeria', 12),
('PRO#208','912EC803B2CE49E4A541068D495AB570','59612211Y','Espejo Serrano', 'Ana Maria@example.com',' Ana Maria', 13),
('PRO#209','912EC803B2CE49E4A541068D495AB570','24260516R','Saiz Piñero', 'Jessica@example.com',' Jessica', 14),
('PRO#210','912EC803B2CE49E4A541068D495AB570','19704241A','Rincon Morcillo', 'Ruth@example.com',' Ruth', 15),
('PRO#211','912EC803B2CE49E4A541068D495AB570','08422001E','Godoy Vidal', 'Asuncion@example.com',' Asuncion', 1),
('PRO#212','912EC803B2CE49E4A541068D495AB570','02231686L','Polo Aparicio', 'Maria Antonia@example.com',' Maria Antonia', 2),
('PRO#213','912EC803B2CE49E4A541068D495AB570','61446251A','Murillo Roca', 'Jaume@example.com',' Jaume', 3),
('PRO#214','912EC803B2CE49E4A541068D495AB570','99266264N','Mendez Aguado', 'Isabel@example.com',' Isabel', 4),
('PRO#215','912EC803B2CE49E4A541068D495AB570','97492548X','Casas Paz', 'Adoracion@example.com',' Adoracion', 5),
('PRO#216','912EC803B2CE49E4A541068D495AB570','96806075H','Delgado Gordillo', 'Jesus Maria@example.com',' Jesus Maria', 6),
('PRO#217','912EC803B2CE49E4A541068D495AB570','95207942V','Vicente Cobos', 'Antonio Jesus@example.com',' Antonio Jesus', 7),
('PRO#218','912EC803B2CE49E4A541068D495AB570','25565275Q','Pujol Martos', 'Juan Carlos@example.com',' Juan Carlos', 8),
('PRO#219','912EC803B2CE49E4A541068D495AB570','01595202Z','Rios Caballero', 'Jose Miguel@example.com',' Jose Miguel', 9),
('PRO#220','912EC803B2CE49E4A541068D495AB570','00718730A','Alba Pons', 'Luis Fernando@example.com',' Luis Fernando', 10),
('PRO#221','912EC803B2CE49E4A541068D495AB570','65948971J','Arranz Pizarro', 'Marco@example.com',' Marco', 1),
('PRO#222','912EC803B2CE49E4A541068D495AB570','88780772J','Simon Belmonte', 'Marcelino@example.com',' Marcelino', 2),
('PRO#223','912EC803B2CE49E4A541068D495AB570','32650799E','Leal Pelaez', 'Herminia@example.com',' Herminia', 3),
('PRO#224','912EC803B2CE49E4A541068D495AB570','49117288Y','Clemente Correa', 'Monica@example.com',' Monica', 4),
('PRO#225','912EC803B2CE49E4A541068D495AB570','95122904X','Esteve Herrero', 'Luis Angel@example.com',' Luis Angel', 5),
('PRO#226','912EC803B2CE49E4A541068D495AB570','10964026H','Casado Cortes', 'Andrea@example.com',' Andrea', 6),
('PRO#227','912EC803B2CE49E4A541068D495AB570','07091205Y','Cardona Collado', 'Alexandre@example.com',' Alexandre', 7),
('PRO#228','912EC803B2CE49E4A541068D495AB570','26701814X','Palacios Llorens', 'Manuel@example.com',' Manuel', 8),
('PRO#229','912EC803B2CE49E4A541068D495AB570','20559173W','Blanco Alfonso', 'Susana@example.com',' Susana', 9),
('PRO#230','912EC803B2CE49E4A541068D495AB570','96827228B','Montes Nieto', 'Gabriela@example.com',' Gabriela', 10),
('PRO#231','912EC803B2CE49E4A541068D495AB570','49564891Y','Valle Velazquez', 'Candida@example.com',' Candida', 11),
('PRO#232','912EC803B2CE49E4A541068D495AB570','68577188C','Ferrero Bonet', 'Cristian@example.com',' Cristian', 12),
('PRO#233','912EC803B2CE49E4A541068D495AB570','32618741A','Villanueva Aguilera', 'Jose Ramon@example.com',' Jose Ramon', 13),
('PRO#234','912EC803B2CE49E4A541068D495AB570','05786389A','Carrasco Alcazar', 'Andreu@example.com',' Andreu', 14),
('PRO#235','912EC803B2CE49E4A541068D495AB570','11934523F','Sevilla Llorens', 'Paola@example.com',' Paola', 15),
('PRO#236','912EC803B2CE49E4A541068D495AB570','03671173M','Villa Ariza', 'Mariana@example.com',' Mariana', 1),
('PRO#237','912EC803B2CE49E4A541068D495AB570','36355996B','Ferreira Correa', 'Maria Inmaculada@example.com',' Maria Inmaculada', 2),
('PRO#238','912EC803B2CE49E4A541068D495AB570','70144741P','Duque Salcedo', 'Alejandra@example.com',' Alejandra', 3),
('PRO#239','912EC803B2CE49E4A541068D495AB570','20728375Q','Benito Barbero', 'Maria Remedios@example.com',' Maria Remedios', 4),
('PRO#240','912EC803B2CE49E4A541068D495AB570','58422506E','Domenech Rey', 'Victoriano@example.com',' Victoriano', 5),
('PRO#241','912EC803B2CE49E4A541068D495AB570','66656308P','Ferreira Maldonado', 'Borja@example.com',' Borja', 6),
('PRO#242','912EC803B2CE49E4A541068D495AB570','03565527K','Galan Noguera', 'Jonathan@example.com',' Jonathan', 7),
('PRO#243','912EC803B2CE49E4A541068D495AB570','46864009Z','Castilla Carbonell', 'Maria Magdalena@example.com',' Maria Magdalena', 8),
('PRO#244','912EC803B2CE49E4A541068D495AB570','42051358K','Cuesta Serrano', 'Ildefonso@example.com',' Ildefonso', 9),
('PRO#245','912EC803B2CE49E4A541068D495AB570','42447337D','Jorge Torres', 'Rogelio@example.com',' Rogelio', 10),
('PRO#246','912EC803B2CE49E4A541068D495AB570','28652129V','Marquez Santiago', 'Maria Esther@example.com',' Maria Esther', 11),
('PRO#247','912EC803B2CE49E4A541068D495AB570','73947592Q','Miranda Salvador', 'Florencio@example.com',' Florencio', 12),
('PRO#248','912EC803B2CE49E4A541068D495AB570','44582874L','Leon Miranda', 'Barbara@example.com',' Barbara', 13),
('PRO#249','912EC803B2CE49E4A541068D495AB570','49952746N','Pino Zamora', 'Nuria@example.com',' Nuria', 14),
('PRO#250','912EC803B2CE49E4A541068D495AB570','83786322J','Contreras Sosa', 'Raquel@example.com',' Raquel', 15),
('PRO#251','912EC803B2CE49E4A541068D495AB570','04318133K','Ojeda Heredia', 'Fernando@example.com',' Fernando', 1),
('PRO#252','912EC803B2CE49E4A541068D495AB570','49063200Z','Galvez Salvador', 'Isidro@example.com',' Isidro', 2),
('PRO#253','912EC803B2CE49E4A541068D495AB570','65897164W','Ariza Criado', 'Estrella@example.com',' Estrella', 3),
('PRO#254','912EC803B2CE49E4A541068D495AB570','69191544T','Olivares Pazos', 'Luis Antonio@example.com',' Luis Antonio', 4),
('PRO#255','912EC803B2CE49E4A541068D495AB570','89558955Z','Barragan Calvo', 'Carolina@example.com',' Carolina', 5),
('PRO#256','912EC803B2CE49E4A541068D495AB570','71426861Q','Lin Lopez', 'Begoña@example.com',' Begoña', 6),
('PRO#257','912EC803B2CE49E4A541068D495AB570','30012665B','Cebrian Singh', 'Ezequiel@example.com',' Ezequiel', 7),
('PRO#258','912EC803B2CE49E4A541068D495AB570','16498815H','Lara Sola', 'Alfonso@example.com',' Alfonso', 8),
('PRO#259','912EC803B2CE49E4A541068D495AB570','15562370H','Arroyo Montes', 'Jose Andres@example.com',' Jose Andres', 9),
('PRO#260','912EC803B2CE49E4A541068D495AB570','66463342N','Ordoñez Duarte', 'Eugenio@example.com',' Eugenio', 10),
('PRO#261','912EC803B2CE49E4A541068D495AB570','14744481D','Abad Ochoa', 'Maria Consuelo@example.com',' Maria Consuelo', 11),
('PRO#262','912EC803B2CE49E4A541068D495AB570','53480443S','Rebollo Llorente', 'Maria Mar@example.com',' Maria Mar', 12),
('PRO#263','912EC803B2CE49E4A541068D495AB570','92028592A','Corrales Valls', 'Maria Begoña@example.com',' Maria Begoña', 13),
('PRO#264','912EC803B2CE49E4A541068D495AB570','70140762P','Lazaro Olivares', 'Eva@example.com',' Eva', 14),
('PRO#265','912EC803B2CE49E4A541068D495AB570','13666514Y','Barragan Brito', 'Hassan@example.com',' Hassan', 15),
('PRO#266','912EC803B2CE49E4A541068D495AB570','91860648M','Sola Cabello', 'Carolina@example.com',' Carolina', 1),
('PRO#267','912EC803B2CE49E4A541068D495AB570','81967550N','Brito Castilla', 'Paloma@example.com',' Paloma', 2),
('PRO#268','912EC803B2CE49E4A541068D495AB570','12780784Y','Gomez Contreras', 'Francisco Jose@example.com',' Francisco Jose', 3),
('PRO#269','912EC803B2CE49E4A541068D495AB570','32916744H','Davila Grau', 'Asier@example.com',' Asier', 4),
('PRO#270','912EC803B2CE49E4A541068D495AB570','55885029C','Anton Arranz', 'Jose Juan@example.com',' Jose Juan', 5),
('PRO#271','912EC803B2CE49E4A541068D495AB570','80583716L','Mateo Saiz', 'Estela@example.com',' Estela', 6),
('PRO#272','912EC803B2CE49E4A541068D495AB570','53325940A','Roldan Madrid', 'Caridad@example.com',' Caridad', 7),
('PRO#273','912EC803B2CE49E4A541068D495AB570','06748487B','Vazquez Del Valle', 'Estefania@example.com',' Estefania', 8),
('PRO#274','912EC803B2CE49E4A541068D495AB570','09042179M','Aguirre Casas', 'Leo@example.com',' Leo', 9),
('PRO#275','912EC803B2CE49E4A541068D495AB570','31618057A','Agudo Cervera', 'Roger@example.com',' Roger', 10),
('PRO#276','912EC803B2CE49E4A541068D495AB570','91690066Z','Palomo Solis', 'Marco Antonio@example.com',' Marco Antonio', 11),
('PRO#277','912EC803B2CE49E4A541068D495AB570','90043496Z','Quesada Ferreiro', 'Sagrario@example.com',' Sagrario', 12),
('PRO#278','912EC803B2CE49E4A541068D495AB570','39047783Q','Villa Granados', 'Aranzazu@example.com',' Aranzazu', 13),
('PRO#279','912EC803B2CE49E4A541068D495AB570','38357589Y','Montero Mesa', 'Ian@example.com',' Ian', 14),
('PRO#280','912EC803B2CE49E4A541068D495AB570','59233949W','Valle Galindo', 'Aina@example.com',' Aina', 15),
('PRO#281','912EC803B2CE49E4A541068D495AB570','96370632B','Valverde Marquez', 'Esther@example.com',' Esther', 1),
('PRO#282','912EC803B2CE49E4A541068D495AB570','70570638Z','Roig Gonzalez', 'Leticia@example.com',' Leticia', 2),
('PRO#283','912EC803B2CE49E4A541068D495AB570','42627271Z','Molina Alonso', 'Maria Purificacion@example.com',' Maria Purificacion', 3),
('PRO#284','912EC803B2CE49E4A541068D495AB570','68067563Y','Alcaide Bonilla', 'Rocio@example.com',' Rocio', 4),
('PRO#285','912EC803B2CE49E4A541068D495AB570','57280486K','Gordillo Vives', 'Fidel@example.com',' Fidel', 5),
('PRO#286','912EC803B2CE49E4A541068D495AB570','25001934Z','Iglesias Huertas', 'Jose Javier@example.com',' Jose Javier', 6),
('PRO#287','912EC803B2CE49E4A541068D495AB570','17084953R','Paniagua Arias', 'Ander@example.com',' Ander', 7),
('PRO#288','912EC803B2CE49E4A541068D495AB570','43949222V','Ramos Sosa', 'Maria Montserrat@example.com',' Maria Montserrat', 8),
('PRO#289','912EC803B2CE49E4A541068D495AB570','06951384W','Varela Perez', 'Aurelia@example.com',' Aurelia', 9),
('PRO#290','912EC803B2CE49E4A541068D495AB570','09702609J','Lobato Llorens', 'Maria Inmaculada@example.com',' Maria Inmaculada', 10),
('PRO#291','912EC803B2CE49E4A541068D495AB570','13463437L','Santana Pereira', 'Nerea@example.com',' Nerea', 11),
('PRO#292','912EC803B2CE49E4A541068D495AB570','41872706X','Clemente Ocaña', 'Margarita@example.com',' Margarita', 12),
('PRO#293','912EC803B2CE49E4A541068D495AB570','22477540P','Pavon Contreras', 'Jose Angel@example.com',' Jose Angel', 13),
('PRO#294','912EC803B2CE49E4A541068D495AB570','72650618N','Silva De La Torre', 'Ismael@example.com',' Ismael', 14),
('PRO#295','912EC803B2CE49E4A541068D495AB570','31857829T','Wang Bonilla', 'Rosario@example.com',' Rosario', 15),
('PRO#296','912EC803B2CE49E4A541068D495AB570','15902914R','Pelaez Barrio', 'Maria Mar@example.com',' Maria Mar', 1),
('PRO#297','912EC803B2CE49E4A541068D495AB570','79159517A','Correa Casado', 'Iñigo@example.com',' Iñigo', 2),
('PRO#298','912EC803B2CE49E4A541068D495AB570','22669136Z','Casas Carvajal', 'Raul@example.com',' Raul', 3),
('PRO#299','912EC803B2CE49E4A541068D495AB570','51991129C','Ruiz Garrido', 'Eva Maria@example.com',' Eva Maria', 4),
('PRO#300','912EC803B2CE49E4A541068D495AB570','22250791Q','Pardo Frias', 'Aranzazu@example.com',' Aranzazu', 5),
('PRO#301','912EC803B2CE49E4A541068D495AB570','49206646D','Domingo Bueno', 'Rosa Maria@example.com',' Rosa Maria', 6),
('PRO#302','912EC803B2CE49E4A541068D495AB570','80621576K','Burgos Bueno', 'Igor@example.com',' Igor', 7),
('PRO#303','912EC803B2CE49E4A541068D495AB570','73047658A','Gil Pino', 'Benjamin@example.com',' Benjamin', 8),
('PRO#304','912EC803B2CE49E4A541068D495AB570','72128948M','Duarte Ortiz', 'Adrian@example.com',' Adrian', 9),
('PRO#305','912EC803B2CE49E4A541068D495AB570','24282032N','Velasco Moran', 'Lidia@example.com',' Lidia', 10),
('PRO#306','912EC803B2CE49E4A541068D495AB570','07606725G','Granados Cardona', 'Vasile@example.com',' Vasile', 11),
('PRO#307','912EC803B2CE49E4A541068D495AB570','31186730H','Aragon Arranz', 'Alexandra@example.com',' Alexandra', 12),
('PRO#308','912EC803B2CE49E4A541068D495AB570','43619490J','Bonilla Lago', 'Alexis@example.com',' Alexis', 13),
('PRO#309','912EC803B2CE49E4A541068D495AB570','17935762V','Juan Aznar', 'Elias@example.com',' Elias', 14),
('PRO#310','912EC803B2CE49E4A541068D495AB570','19653102Q','Martin Hurtado', 'Maria Manuela@example.com',' Maria Manuela', 15),
('PRO#311','912EC803B2CE49E4A541068D495AB570','87495503F','Cordero Campos', 'Naiara@example.com',' Naiara', 6),
('PRO#312','912EC803B2CE49E4A541068D495AB570','38673770Y','Del Rio Fraile', 'Kevin@example.com',' Kevin', 7),
('PRO#313','912EC803B2CE49E4A541068D495AB570','00840863Y','Abad Wang', 'Igor@example.com',' Igor', 8),
('PRO#314','912EC803B2CE49E4A541068D495AB570','92404967Y','Galvez Blasco', 'Alberto@example.com',' Alberto', 9),
('PRO#315','912EC803B2CE49E4A541068D495AB570','62521101V','Ramirez Ochoa', 'Albert@example.com',' Albert', 10),
('PRO#316','912EC803B2CE49E4A541068D495AB570','37944035S','Hernando Cordero', 'Maria Belen@example.com',' Maria Belen', 11),
('PRO#317','912EC803B2CE49E4A541068D495AB570','67045193D','Alfaro Barreiro', 'Samuel@example.com',' Samuel', 12),
('PRO#318','912EC803B2CE49E4A541068D495AB570','68481931Y','Cardona Huerta', 'Rafael@example.com',' Rafael', 13),
('PRO#319','912EC803B2CE49E4A541068D495AB570','75627578J','Lobato Brito', 'Paulino@example.com',' Paulino', 14),
('PRO#320','912EC803B2CE49E4A541068D495AB570','66946733N','Cervera Estrada', 'Aranzazu@example.com',' Aranzazu', 15);
--Insertar Pacientes
-- Insertar Pacientes
INSERT INTO myhealth.patient(personalidentificationcode, password, nif, surname, email, name, familydoctorid) VALUES
('PAT#100','912EC803B2CE49E4A541068D495AB570','97758900E','Singh Vila', 'Soledad@example.ecom','Soledad', 1)
,('PAT#101','912EC803B2CE49E4A541068D495AB570','Z9518183Y','Jimenez Merino', 'Ainhoa@example.ecom','Ainhoa', 2)
,('PAT#102','912EC803B2CE49E4A541068D495AB570','97758900E','Jesus Chen Barba', 'Abel@example.ecom','Abel', 3)
,('PAT#103','912EC803B2CE49E4A541068D495AB570','95014341F','Lorenzo Tapia Navas', 'Francisco@example.ecom','Francisco', 4)
,('PAT#104','912EC803B2CE49E4A541068D495AB570','17873499S','Gimenez Gutierrez', 'Teodora@example.ecom','Teodora', 5)
,('PAT#105','912EC803B2CE49E4A541068D495AB570','07320674G','Escobar Marquez', 'Jorge@example.ecom','Jorge', 6)
,('PAT#106','912EC803B2CE49E4A541068D495AB570','63888801E','Marin Reina', 'Marti@example.ecom','Marti', 7)
,('PAT#107','912EC803B2CE49E4A541068D495AB570','36676167E','Bosch Zapata', 'Abril@example.ecom','Abril', 8)
,('PAT#108','912EC803B2CE49E4A541068D495AB570','73569670F','Bosch Zapata', 'Esperanza@example.ecom','Esperanza', 9)
,('PAT#109','912EC803B2CE49E4A541068D495AB570','53986482P','Carretero Ayala', 'Eduardo@example.ecom','Eduardo', 10);
('PAT#100','912EC803B2CE49E4A541068D495AB570','97758900E','Singh Vila', 'Soledad@example.com','Soledad', 1)
,('PAT#101','912EC803B2CE49E4A541068D495AB570','Z9518183Y','Jimenez Merino', 'Ainhoa@example.com','Ainhoa', 2)
,('PAT#102','912EC803B2CE49E4A541068D495AB570','49426296D','Jesus Chen Barba', 'Abel@example.com','Abel', 3)
,('PAT#103','912EC803B2CE49E4A541068D495AB570','95014341F','Lorenzo Tapia Navas', 'Francisco@example.com','Francisco', 4)
,('PAT#104','912EC803B2CE49E4A541068D495AB570','17873499S','Gimenez Gutierrez', 'Teodora@example.com','Teodora', 5)
,('PAT#105','912EC803B2CE49E4A541068D495AB570','07320674G','Escobar Marquez', 'Jorge@example.com','Jorge', 6)
,('PAT#106','912EC803B2CE49E4A541068D495AB570','63888801E','Marin Reina', 'Marti@example.com','Marti', 7)
,('PAT#107','912EC803B2CE49E4A541068D495AB570','36676167E','Bosch Zapata', 'Abril@example.com','Abril', 8)
,('PAT#108','912EC803B2CE49E4A541068D495AB570','73569670F','Bosch Zapata', 'Esperanza@example.com','Esperanza', 9)
,('PAT#109','912EC803B2CE49E4A541068D495AB570','53986482P','Carretero Ayala', 'Eduardo@example.com','Eduardo', 10);
-- Insertar datos de prueba para preguntas
INSERT INTO myhealth.question(title, message, status, response, patientid, familydoctorid) VALUES
('titulo de la pregunta número 1', 'Doctor, tengo dolor en la articulación numero 1', 'PENDING', null, 1, 1)
,('titulo de la pregunta número 2', 'Doctor, tengo dolor en la articulación numero 2', 'PENDING', null, 2, 1)
@@ -105,5 +614,58 @@ INSERT INTO myhealth.question(title, message, status, response, patientid, famil
,('titulo de la pregunta número 22', 'Doctor, tengo dolor en la articulación numero 22', 'PENDING', null, 9, 1)
,('titulo de la pregunta número 23', 'Doctor, tengo dolor en la articulación numero 23', 'PENDING', null, 10, 1);
-- Insertar datos de prueba para visitas
INSERT INTO myhealth.visit(date, "time", observations, result, patientid, familydoctorid) VALUES
('2019-12-23','09:00:00','Observaciones de la visita 43822','',1,1),
('2019-12-24','10:00:00','Observaciones de la visita 43823','',2,1),
('2019-12-25','11:00:00','Observaciones de la visita 43824','',3,1),
('2019-12-26','12:00:00','Observaciones de la visita 43825','',4,1),
('2019-12-27','13:00:00','Observaciones de la visita 43826','',5,1),
('2019-12-28','14:00:00','Observaciones de la visita 43827','',6,1),
('2019-12-29','15:00:00','Observaciones de la visita 43828','',7,1),
('2019-12-30','16:00:00','Observaciones de la visita 43829','',8,1),
('2019-12-31','17:00:00','Observaciones de la visita 43830','',9,1),
('2020-01-01','18:00:00','Observaciones de la visita 43831','',10,1),
('2019-12-23','09:00:00','Observaciones de la visita 43822','',1,1),
('2019-12-23','10:00:00','Observaciones de la visita 43822','',2,1),
('2019-12-23','11:00:00','Observaciones de la visita 43822','',3,1),
('2019-12-23','12:00:00','Observaciones de la visita 43822','',4,1),
('2019-12-23','13:00:00','Observaciones de la visita 43822','',5,1),
('2019-12-23','14:00:00','Observaciones de la visita 43822','',6,1),
('2019-12-23','15:00:00','Observaciones de la visita 43822','',7,1),
('2019-12-23','16:00:00','Observaciones de la visita 43822','',8,1),
('2019-12-23','17:00:00','Observaciones de la visita 43822','',9,1),
('2019-12-23','18:00:00','Observaciones de la visita 43822','',10,1),
('2019-12-23','09:00:00','Observaciones de la visita 43822','',1,2),
('2019-12-23','10:00:00','Observaciones de la visita 43822','',2,2),
('2019-12-23','11:00:00','Observaciones de la visita 43822','',3,2),
('2019-12-23','12:00:00','Observaciones de la visita 43822','',4,2),
('2019-12-23','13:00:00','Observaciones de la visita 43822','',5,2),
('2019-12-23','14:00:00','Observaciones de la visita 43822','',6,2),
('2019-12-23','15:00:00','Observaciones de la visita 43822','',7,2),
('2019-12-23','16:00:00','Observaciones de la visita 43822','',8,2),
('2019-12-23','17:00:00','Observaciones de la visita 43822','',9,2),
('2019-12-23','18:00:00','Observaciones de la visita 43822','',10,2),
('2019-12-23','09:00:00','Observaciones de la visita 43822','',1,2),
('2020-01-23','10:00:00','Observaciones de la visita 43853','',2,2),
('2020-01-24','11:00:00','Observaciones de la visita 43854','',3,2),
('2020-01-25','12:00:00','Observaciones de la visita 43855','',4,2),
('2020-01-26','13:00:00','Observaciones de la visita 43856','',5,2),
('2020-01-27','14:00:00','Observaciones de la visita 43857','',6,2),
('2020-01-28','15:00:00','Observaciones de la visita 43858','',7,2),
('2020-01-29','16:00:00','Observaciones de la visita 43859','',8,2),
('2020-01-30','17:00:00','Observaciones de la visita 43860','',9,2),
('2020-01-31','18:00:00','Observaciones de la visita 43861','',10,2);
-- Insertar datos de prueba para medical test
INSERT INTO myhealth.medicaltest(date, "time", observations, highresimage, type, patientid, specialistdoctorid) VALUES
('2019-12-23','09:00:00','Observaciones del medical test1','somehighresimage1', 'MAGNETIC_RESONANCE_IMAGING', 1, 1),
('2019-12-24','19:20:00','Observaciones del medical test2','somehighresimage2', 'CT_SCAN', 1, 1),
('2019-12-25','18:35:20','Observaciones del medical test3','somehighresimage3', 'BLOOD_TEST', 1, 1),
('2019-12-26','08:15:10','Observaciones del medical test4','somehighresimage4', 'CT_SCAN', 4, 2),
('2019-12-27','18:15:10','Observaciones del medical test5','somehighresimage5', 'CT_SCAN', 5, 1),
('2019-12-28','22:15:40','Observaciones del medical test6','somehighresimage6', 'MAGNETIC_RESONANCE_IMAGING', 6, 3),
('2019-12-28','23:15:40','Observaciones del medical test7','somehighresimage7', 'MAGNETIC_RESONANCE_IMAGING', 7, 1),
('2019-12-29','11:12:20','Observaciones del medical test8','somehighresimage8', 'CT_SCAN', 8, 1),
('2019-12-30','13:17:50','Observaciones del medical test9','somehighresimage9', 'MAGNETIC_RESONANCE_IMAGING', 2, 2),
('2019-12-31','05:08:30','Observaciones del medical test10','somehighresimage10', 'MAGNETIC_RESONANCE_IMAGING', 4, 1);

3
2.database/executeall.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
psql -U postgres -f 01.CreateTables.sql
psql -U postgres -f 02.Datos_prueba.sql

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,92 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Wed Dec 18 17:32:33 2019
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.
set force_conservative 0 ;# set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#
# 2) differing output - Some programs produce different output each time
# they run. The "date" command is an obvious example. Another is
# ftp, if it produces throughput statistics at the end of a file
# transfer. If this causes a problem, delete these patterns or replace
# them with wildcards. An alternative is to use the -p flag (for
# "prompt") which makes Expect only look for the last line of output
# (i.e., the prompt). The -P flag allows you to define a character to
# toggle this mode off and on.
#
# Read the man page for more info.
#
# -Don
set timeout -1
spawn ./add-user.sh
match_max 100000
expect -exact "\r
What type of user do you wish to add? \r
a) Management User (mgmt-users.properties) \r
b) Application User (application-users.properties)\r
(a): "
send -- "b\r"
expect -exact "b\r
\r
Enter the details of the new user to add.\r
Using realm 'ApplicationRealm' as discovered from the existing property files.\r
Username : "
send -- "USER\r"
expect -exact "USER\r
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.\r
- The password should be different from the username\r
- The password should not be one of the following restricted values {root, admin, administrator}\r
- The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)\r
Password : "
send -- "PASSWORD\r"
expect -exact "\r
WFLYDM0101: Password should have at least 1 digit.\r
Are you sure you want to use the password entered yes/no? "
send -- "Y\r"
expect -exact "Y\r
Re-enter Password : "
send -- "PASSWORD\r"
expect -exact "\r
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)\[ \]: "
send -- " User,Trainer,Administrator"
expect -exact " User,Trainer,Administrator"
send -- "\r"
expect -exact "\r
About to add user 'USER' for realm 'ApplicationRealm'\r
Is this correct yes/no? "
send -- "Y\r"
expect -exact "Y\r
Added user 'USER' to file '/opt/jboss/wildfly/standalone/configuration/application-users.properties'\r
Added user 'USER' to file '/opt/jboss/wildfly/domain/configuration/application-users.properties'\r
Added user 'USER' with groups User,Trainer,Administrator to file '/opt/jboss/wildfly/standalone/configuration/application-roles.properties'\r
Added user 'USER' with groups User,Trainer,Administrator to file '/opt/jboss/wildfly/domain/configuration/application-roles.properties'\r
Is this new user going to be used for one AS process to connect to another AS process? \r
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.\r
yes/no? "
send -- "Y\r"
expect eof

View File

@@ -0,0 +1,92 @@
#!/usr/bin/expect -f
#
# This Expect script was generated by autoexpect on Wed Dec 18 17:37:57 2019
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.
set force_conservative 0 ;# set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#
# 2) differing output - Some programs produce different output each time
# they run. The "date" command is an obvious example. Another is
# ftp, if it produces throughput statistics at the end of a file
# transfer. If this causes a problem, delete these patterns or replace
# them with wildcards. An alternative is to use the -p flag (for
# "prompt") which makes Expect only look for the last line of output
# (i.e., the prompt). The -P flag allows you to define a character to
# toggle this mode off and on.
#
# Read the man page for more info.
#
# -Don
set timeout -1
spawn ./add-user.sh
match_max 100000
expect -exact "\r
What type of user do you wish to add? \r
a) Management User (mgmt-users.properties) \r
b) Application User (application-users.properties)\r
(a): "
send -- "A\r"
expect -exact "A\r
\r
Enter the details of the new user to add.\r
Using realm 'ManagementRealm' as discovered from the existing property files.\r
Username : "
send -- "USER\r"
expect -exact "USER\r
Password recommendations are listed below. To modify these restrictions edit the add-user.properties configuration file.\r
- The password should be different from the username\r
- The password should not be one of the following restricted values {root, admin, administrator}\r
- The password should contain at least 8 characters, 1 alphabetic character(s), 1 digit(s), 1 non-alphanumeric symbol(s)\r
Password : "
send -- "PASSWORD\r"
expect -exact "\r
WFLYDM0101: Password should have at least 1 digit.\r
Are you sure you want to use the password entered yes/no? "
send -- "Y\r"
expect -exact "Y\r
Re-enter Password : "
send -- "PASSWORD\r"
expect -exact "\r
What groups do you want this user to belong to? (Please enter a comma separated list, or leave blank for none)\[ \]: "
send -- " User,Trainer,Administrator"
expect -exact " User,Trainer,Administrator"
send -- "\r"
expect -exact "\r
About to add user 'USER' for realm 'ManagementRealm'\r
Is this correct yes/no? "
send -- "Y\r"
expect -exact "Y\r
Added user 'USER' to file '/opt/jboss/wildfly/standalone/configuration/mgmt-users.properties'\r
Added user 'USER' to file '/opt/jboss/wildfly/domain/configuration/mgmt-users.properties'\r
Added user 'USER' with groups User,Trainer,Administrator to file '/opt/jboss/wildfly/standalone/configuration/mgmt-groups.properties'\r
Added user 'USER' with groups User,Trainer,Administrator to file '/opt/jboss/wildfly/domain/configuration/mgmt-groups.properties'\r
Is this new user going to be used for one AS process to connect to another AS process? \r
e.g. for a slave host controller connecting to the master or for a Remoting connection for server to server EJB calls.\r
yes/no? "
send -- "Y\r"
expect eof

10
4.config/module.xml Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.postgresql">
<resources>
<resource-root path="postgresql-9.4.1209.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>

BIN
4.config/postgresql-9.4.1209.jar Executable file

Binary file not shown.

524
4.config/standalone.xml Normal file
View File

@@ -0,0 +1,524 @@
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:8.0">
<extensions>
<extension module="org.jboss.as.clustering.infinispan"/>
<extension module="org.jboss.as.connector"/>
<extension module="org.jboss.as.deployment-scanner"/>
<extension module="org.jboss.as.ee"/>
<extension module="org.jboss.as.ejb3"/>
<extension module="org.jboss.as.jaxrs"/>
<extension module="org.jboss.as.jdr"/>
<extension module="org.jboss.as.jmx"/>
<extension module="org.jboss.as.jpa"/>
<extension module="org.jboss.as.jsf"/>
<extension module="org.jboss.as.logging"/>
<extension module="org.jboss.as.mail"/>
<extension module="org.jboss.as.naming"/>
<extension module="org.jboss.as.pojo"/>
<extension module="org.jboss.as.remoting"/>
<extension module="org.jboss.as.sar"/>
<extension module="org.jboss.as.security"/>
<extension module="org.jboss.as.transactions"/>
<extension module="org.jboss.as.webservices"/>
<extension module="org.jboss.as.weld"/>
<extension module="org.wildfly.extension.batch.jberet"/>
<extension module="org.wildfly.extension.bean-validation"/>
<extension module="org.wildfly.extension.core-management"/>
<extension module="org.wildfly.extension.discovery"/>
<extension module="org.wildfly.extension.ee-security"/>
<extension module="org.wildfly.extension.elytron"/>
<extension module="org.wildfly.extension.io"/>
<extension module="org.wildfly.extension.microprofile.config-smallrye"/>
<extension module="org.wildfly.extension.microprofile.health-smallrye"/>
<extension module="org.wildfly.extension.microprofile.opentracing-smallrye"/>
<extension module="org.wildfly.extension.request-controller"/>
<extension module="org.wildfly.extension.security.manager"/>
<extension module="org.wildfly.extension.undertow"/>
</extensions>
<management>
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="ApplicationRealm">
<server-identities>
<ssl>
<keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/>
</ssl>
</server-identities>
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
</security-realms>
<audit-log>
<formatters>
<json-formatter name="json-formatter"/>
</formatters>
<handlers>
<file-handler name="file" formatter="json-formatter" path="audit-log.log" relative-to="jboss.server.data.dir"/>
</handlers>
<logger log-boot="true" log-read-only="false" enabled="false">
<handlers>
<handler name="file"/>
</handlers>
</logger>
</audit-log>
<management-interfaces>
<http-interface security-realm="ManagementRealm">
<http-upgrade enabled="true"/>
<socket-binding http="management-http"/>
</http-interface>
</management-interfaces>
<access-control provider="simple">
<role-mapping>
<role name="SuperUser">
<include>
<user name="$local"/>
</include>
</role>
</role-mapping>
</access-control>
</management>
<profile>
<subsystem xmlns="urn:jboss:domain:logging:6.0">
<console-handler name="CONSOLE">
<level name="INFO"/>
<formatter>
<named-formatter name="COLOR-PATTERN"/>
</formatter>
</console-handler>
<periodic-rotating-file-handler name="FILE" autoflush="true">
<formatter>
<named-formatter name="PATTERN"/>
</formatter>
<file relative-to="jboss.server.log.dir" path="server.log"/>
<suffix value=".yyyy-MM-dd"/>
<append value="true"/>
</periodic-rotating-file-handler>
<logger category="com.arjuna">
<level name="WARN"/>
</logger>
<logger category="org.jboss.as.config">
<level name="DEBUG"/>
</logger>
<logger category="sun.rmi">
<level name="WARN"/>
</logger>
<root-logger>
<level name="INFO"/>
<handlers>
<handler name="CONSOLE"/>
<handler name="FILE"/>
</handlers>
</root-logger>
<formatter name="PATTERN">
<pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>
<formatter name="COLOR-PATTERN">
<pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
</formatter>
</subsystem>
<subsystem xmlns="urn:jboss:domain:batch-jberet:2.0">
<default-job-repository name="in-memory"/>
<default-thread-pool name="batch"/>
<job-repository name="in-memory">
<in-memory/>
</job-repository>
<thread-pool name="batch">
<max-threads count="10"/>
<keepalive-time time="30" unit="seconds"/>
</thread-pool>
</subsystem>
<subsystem xmlns="urn:jboss:domain:bean-validation:1.0"/>
<subsystem xmlns="urn:jboss:domain:core-management:1.0"/>
<subsystem xmlns="urn:jboss:domain:datasources:5.0">
<datasources>
<datasource jta="false" jndi-name="java:jboss/postgresDS" pool-name="postgresDS" enabled="true" use-java-context="true" use-ccm="false">
<connection-url>jdbc:postgresql://postgres:5432/myhealth</connection-url>
<driver-class>org.postgresql.Driver</driver-class>
<driver>postgresql</driver>
<security>
<user-name>USER</user-name>
<password>PASSWORD</password>
</security>
</datasource>
<datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
<connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url>
<driver>h2</driver>
<security>
<user-name>sa</user-name>
<password>sa</password>
</security>
</datasource>
<drivers>
<driver name="postgresql" module="org.postgresql">
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
</driver>
<driver name="h2" module="com.h2database.h2">
<xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
</driver>
</drivers>
</datasources>
</subsystem>
<subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0">
<deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:discovery:1.0"/>
<subsystem xmlns="urn:jboss:domain:ee:4.0">
<spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
<concurrent>
<context-services>
<context-service name="default" jndi-name="java:jboss/ee/concurrency/context/default" use-transaction-setup-provider="true"/>
</context-services>
<managed-thread-factories>
<managed-thread-factory name="default" jndi-name="java:jboss/ee/concurrency/factory/default" context-service="default"/>
</managed-thread-factories>
<managed-executor-services>
<managed-executor-service name="default" jndi-name="java:jboss/ee/concurrency/executor/default" context-service="default" hung-task-threshold="60000" keepalive-time="5000"/>
</managed-executor-services>
<managed-scheduled-executor-services>
<managed-scheduled-executor-service name="default" jndi-name="java:jboss/ee/concurrency/scheduler/default" context-service="default" hung-task-threshold="60000" keepalive-time="3000"/>
</managed-scheduled-executor-services>
</concurrent>
<default-bindings context-service="java:jboss/ee/concurrency/context/default" datasource="java:jboss/datasources/ExampleDS" managed-executor-service="java:jboss/ee/concurrency/executor/default" managed-scheduled-executor-service="java:jboss/ee/concurrency/scheduler/default" managed-thread-factory="java:jboss/ee/concurrency/factory/default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:ee-security:1.0"/>
<subsystem xmlns="urn:jboss:domain:ejb3:5.0">
<session-bean>
<stateless>
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
</stateless>
<stateful default-access-timeout="5000" cache-ref="simple" passivation-disabled-cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
<pools>
<bean-instance-pools>
<strict-max-pool name="mdb-strict-max-pool" derive-size="from-cpu-count" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
<strict-max-pool name="slsb-strict-max-pool" derive-size="from-worker-pools" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/>
</bean-instance-pools>
</pools>
<caches>
<cache name="simple"/>
<cache name="distributable" passivation-store-ref="infinispan" aliases="passivating clustered"/>
</caches>
<passivation-stores>
<passivation-store name="infinispan" cache-container="ejb" max-size="10000"/>
</passivation-stores>
<async thread-pool-name="default"/>
<timer-service thread-pool-name="default" default-data-store="default-file-store">
<data-stores>
<file-data-store name="default-file-store" path="timer-service-data" relative-to="jboss.server.data.dir"/>
</data-stores>
</timer-service>
<remote connector-ref="http-remoting-connector" thread-pool-name="default">
<channel-creation-options>
<option name="READ_TIMEOUT" value="${prop.remoting-connector.read.timeout:20}" type="xnio"/>
<option name="MAX_OUTBOUND_MESSAGES" value="1234" type="remoting"/>
</channel-creation-options>
</remote>
<thread-pools>
<thread-pool name="default">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
<default-security-domain value="other"/>
<default-missing-method-permissions-deny-access value="true"/>
<log-system-exceptions value="true"/>
</subsystem>
<subsystem xmlns="urn:wildfly:elytron:4.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
<providers>
<aggregate-providers name="combined-providers">
<providers name="elytron"/>
<providers name="openssl"/>
</aggregate-providers>
<provider-loader name="elytron" module="org.wildfly.security.elytron"/>
<provider-loader name="openssl" module="org.wildfly.openssl"/>
</providers>
<audit-logging>
<file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/>
</audit-logging>
<security-domains>
<security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper">
<realm name="ApplicationRealm" role-decoder="groups-to-roles"/>
<realm name="local"/>
</security-domain>
<security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper">
<realm name="ManagementRealm" role-decoder="groups-to-roles"/>
<realm name="local" role-mapper="super-user-mapper"/>
</security-domain>
</security-domains>
<security-realms>
<identity-realm name="local" identity="$local"/>
<properties-realm name="ApplicationRealm">
<users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/>
<groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</properties-realm>
<properties-realm name="ManagementRealm">
<users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/>
<groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</properties-realm>
</security-realms>
<mappers>
<simple-permission-mapper name="default-permission-mapper" mapping-mode="first">
<permission-mapping>
<principal name="anonymous"/>
<permission-set name="default-permissions"/>
</permission-mapping>
<permission-mapping match-all="true">
<permission-set name="login-permission"/>
<permission-set name="default-permissions"/>
</permission-mapping>
</simple-permission-mapper>
<constant-realm-mapper name="local" realm-name="local"/>
<simple-role-decoder name="groups-to-roles" attribute="groups"/>
<constant-role-mapper name="super-user-mapper">
<role name="SuperUser"/>
</constant-role-mapper>
</mappers>
<permission-sets>
<permission-set name="login-permission">
<permission class-name="org.wildfly.security.auth.permission.LoginPermission"/>
</permission-set>
<permission-set name="default-permissions">
<permission class-name="org.wildfly.extension.batch.jberet.deployment.BatchPermission" module="org.wildfly.extension.batch.jberet" target-name="*"/>
<permission class-name="org.wildfly.transaction.client.RemoteTransactionPermission" module="org.wildfly.transaction.client"/>
<permission class-name="org.jboss.ejb.client.RemoteEJBPermission" module="org.jboss.ejb-client"/>
</permission-set>
</permission-sets>
<http>
<http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="DIGEST">
<mechanism-realm realm-name="ManagementRealm"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
<provider-http-server-mechanism-factory name="global"/>
</http>
<sasl>
<sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
<mechanism-configuration>
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
<mechanism mechanism-name="DIGEST-MD5">
<mechanism-realm realm-name="ApplicationRealm"/>
</mechanism>
</mechanism-configuration>
</sasl-authentication-factory>
<sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain">
<mechanism-configuration>
<mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/>
<mechanism mechanism-name="DIGEST-MD5">
<mechanism-realm realm-name="ManagementRealm"/>
</mechanism>
</mechanism-configuration>
</sasl-authentication-factory>
<configurable-sasl-server-factory name="configured" sasl-server-factory="elytron">
<properties>
<property name="wildfly.sasl.local-user.default-user" value="$local"/>
</properties>
</configurable-sasl-server-factory>
<mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global">
<filters>
<filter provider-name="WildFlyElytron"/>
</filters>
</mechanism-provider-filtering-sasl-server-factory>
<provider-sasl-server-factory name="global"/>
</sasl>
</subsystem>
<subsystem xmlns="urn:jboss:domain:infinispan:7.0">
<cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
<local-cache name="default">
<transaction mode="BATCH"/>
</local-cache>
</cache-container>
<cache-container name="web" default-cache="passivation" module="org.wildfly.clustering.web.infinispan">
<local-cache name="passivation">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store passivation="true" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="ejb" aliases="sfsb" default-cache="passivation" module="org.wildfly.clustering.ejb.infinispan">
<local-cache name="passivation">
<locking isolation="REPEATABLE_READ"/>
<transaction mode="BATCH"/>
<file-store passivation="true" purge="false"/>
</local-cache>
</cache-container>
<cache-container name="hibernate" module="org.infinispan.hibernate-cache">
<local-cache name="entity">
<transaction mode="NON_XA"/>
<object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="local-query">
<object-memory size="10000"/>
<expiration max-idle="100000"/>
</local-cache>
<local-cache name="timestamps"/>
</cache-container>
</subsystem>
<subsystem xmlns="urn:jboss:domain:io:3.0">
<worker name="default"/>
<buffer-pool name="default"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/>
<subsystem xmlns="urn:jboss:domain:jca:5.0">
<archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/>
<bean-validation enabled="true"/>
<default-workmanager>
<short-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</short-running-threads>
<long-running-threads>
<core-threads count="50"/>
<queue-length count="50"/>
<max-threads count="50"/>
<keepalive-time time="10" unit="seconds"/>
</long-running-threads>
</default-workmanager>
<cached-connection-manager/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jdr:1.0"/>
<subsystem xmlns="urn:jboss:domain:jmx:1.3">
<expose-resolved-model/>
<expose-expression-model/>
<remoting-connector/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jpa:1.1">
<jpa default-datasource="" default-extended-persistence-inheritance="DEEP"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:jsf:1.1"/>
<subsystem xmlns="urn:jboss:domain:mail:3.0">
<mail-session name="default" jndi-name="java:jboss/mail/Default">
<smtp-server outbound-socket-binding-ref="mail-smtp"/>
</mail-session>
</subsystem>
<subsystem xmlns="urn:wildfly:microprofile-config-smallrye:1.0"/>
<subsystem xmlns="urn:wildfly:microprofile-health-smallrye:1.0" security-enabled="false"/>
<subsystem xmlns="urn:wildfly:microprofile-opentracing-smallrye:1.0"/>
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<remote-naming/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:pojo:1.0"/>
<subsystem xmlns="urn:jboss:domain:remoting:4.0">
<http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:request-controller:1.0"/>
<subsystem xmlns="urn:jboss:domain:resource-adapters:5.0"/>
<subsystem xmlns="urn:jboss:domain:sar:1.0"/>
<subsystem xmlns="urn:jboss:domain:security:2.0">
<security-domains>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="jboss-web-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<security-domain name="jaspitest" cache-type="default">
<authentication-jaspi>
<login-module-stack name="dummy">
<login-module code="Dummy" flag="optional"/>
</login-module-stack>
<auth-module code="Dummy"/>
</authentication-jaspi>
</security-domain>
<security-domain name="jboss-ejb-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
</security-domains>
</subsystem>
<subsystem xmlns="urn:jboss:domain:security-manager:1.0">
<deployment-permissions>
<maximum-set>
<permission class="java.security.AllPermission"/>
</maximum-set>
</deployment-permissions>
</subsystem>
<subsystem xmlns="urn:jboss:domain:transactions:5.0">
<core-environment node-identifier="${jboss.tx.node.id:1}">
<process-id>
<uuid/>
</process-id>
</core-environment>
<recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/>
<object-store path="tx-object-store" relative-to="jboss.server.data.dir"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:undertow:7.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
<servlet-container name="default">
<jsp-config/>
<websockets/>
</servlet-container>
<handlers>
<file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
</handlers>
</subsystem>
<subsystem xmlns="urn:jboss:domain:webservices:2.0">
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
<subsystem xmlns="urn:jboss:domain:weld:4.0"/>
</profile>
<interfaces>
<interface name="management">
<inet-address value="${jboss.bind.address.management:127.0.0.1}"/>
</interface>
<interface name="public">
<inet-address value="${jboss.bind.address:127.0.0.1}"/>
</interface>
</interfaces>
<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
<socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/>
<socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/>
<socket-binding name="ajp" port="${jboss.ajp.port:8009}"/>
<socket-binding name="http" port="${jboss.http.port:8080}"/>
<socket-binding name="https" port="${jboss.https.port:8443}"/>
<socket-binding name="txn-recovery-environment" port="4712"/>
<socket-binding name="txn-status-manager" port="4713"/>
<outbound-socket-binding name="mail-smtp">
<remote-destination host="localhost" port="25"/>
</outbound-socket-binding>
</socket-binding-group>
</server>

29
Dockerfile Normal file
View File

@@ -0,0 +1,29 @@
FROM jboss/wildfly:14.0.1.Final
# User root user to install software
USER root
RUN yum -y install expect
RUN yum -y install postgresql
RUN yum -y install ant
# Compile and copy .ear to deployments
ADD ./1.sources/ /opt/jboss/
RUN cd /opt/jboss/MyHealth && ant
RUN mv /opt/jboss/MyHealth/dist/MyHealth.ear /opt/jboss/wildfly/standalone/deployments
# Switch back to jboss user
USER jboss
ADD ./4.config/createApplicationUser.sh /opt/jboss/wildfly/bin/
ADD ./4.config/createManagementUser.sh /opt/jboss/wildfly/bin/
RUN cd /opt/jboss/wildfly/bin && ./createApplicationUser.sh
RUN cd /opt/jboss/wildfly/bin && ./createManagementUser.sh
RUN mkdir /opt/jboss/wildfly/modules/system/layers/base/org/postgresql/
RUN mkdir /opt/jboss/wildfly/modules/system/layers/base/org/postgresql/main
ADD ./4.config/postgresql-9.4.1209.jar /opt/jboss/wildfly/modules/system/layers/base/org/postgresql/main
ADD ./4.config/module.xml /opt/jboss/wildfly/modules/system/layers/base/org/postgresql/main
ADD ./4.config/standalone.xml /opt/jboss/wildfly/standalone/configuration/standalone.xml
CMD ["/opt/jboss/wildfly/bin/standalone.sh", "-b", "0.0.0.0", "-bmanagement", "0.0.0.0"]

24
docker-compose.yml Normal file
View File

@@ -0,0 +1,24 @@
version: '3'
services:
postgres:
image: postgres:10.11-alpine
ports:
- "5432:5432"
environment:
- POSTGRES_USER=USER
- POSTGRES_PASSWORD=PASSWORD
- POSTGRES_DB=myhealth
volumes:
- ./2.database/01.CreateTables.sql:/docker-entrypoint-initdb.d/01.CreateTables.sql
- ./2.database/02.Datos_prueba.sql:/docker-entrypoint-initdb.d/02.Datos_prueba.sql
wildfly:
build: .
ports:
- "8080:8080"
environment:
- DB_USER=USER
- DB_PASS=PASSWORD
- JBOSS_HOME=/opt/jboss/wildfly
depends_on:
- postgres

View File

@@ -1,6 +1,8 @@
## Instrucciones de despliegue e instalación
### 1. Crear esquema de base de datos y tablas:
Se debe crear un esquema nuevo en PostgreSQL y conceder permisos al usuario USER. Esto puede realizarse ejecutando el script incluido con la solución llamado:
Se utilizará la base de datos por defecto de postgres llamada "postgres", si se tuiliza otra deberá reflejarse en paso 3 a la hora de configurar el datasource.
También se asume que el servidor de postgres está ubicado en localhost (en la misma máquina donde se ejecutan los EJBs)
Se debe crear un esquema nuevo en PostgreSQL, el esquema debe llamarse "myhealth", se deben conceder permisos al usuario USER. Estas accione (crear el esquema y el usuario) las realiza el script incluido con la solución llamado:
* 01.CreateTables.sql
### 2. Inserción de datos iniciales:
@@ -22,5 +24,35 @@ El usuario y contraseña de base de datos que se han utilizado en el datasource
</security>
</datasource>
### 4. Ejecutar la compilación y despliegue del proyecto
### 4. Configuración del driver de postgresql en JBOSS
Este proyecto utiliza el mismo driver que el utilizado en el caso practico del laboratorio. Si el entorno no está configurado, deberá configurarse el driver Postgresql en JBOSS. Para ello se debe añadir en el fichero JBOSS_HOME\standalone\configuration\standalone.xlm la siguiente configuración en el nodo <drivers>:
<driver name="postgresql" module="org.postgresql">
<xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
</driver>
Además, es necesario configurar la libreria (jar) de postgres en JBOSS. La configuración es la misma que para el caso practico. Crear el archivo modules.xml en el directorio /opt/wildfly/modules/system/layers/base/org/postgresql/main
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.postgresql">
<resources>
<resource-root path="postgresql-9.4.1209.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
También se debe copiar el fichero postgresql-9.4.1209.jar en la misma ruta: /opt/wildfly/modules/system/layers/base/org/postgresql/main
### 5. Ejecutar la compilación y despliegue del proyecto
Acceder al directorio con el código fuente ([git-folder]/1.sources/MyHealth), y donde está ubicado el archivo de compilación de ant build.xml, ejecutar `ant` en este directorio, el proyecto debería compilarse y desplegarse automáticamente en el servidor JBOSS local.
## Instrucciones de despliegue alternativo con docker
### pre-requisitos:
Instalar docker desktop
### Levantar ambiente con un solo comando:
Abrimos la consola y nos posicionamos en el root del proyecto donde se encuentra el archivo `docker-compose.yml` y mediante la ejecución del comando `docker-compose up` levantaremos un contenedor de postgresql con el schema, tablas y permisos configurado y un contenedor con jboss/wildfly también configurado en el que compilaremos la ultima versión del producto y la desplegaremos.