Merge branch 'master' into rorden

# Conflicts:
#	2.database/01.CreateTables.sql
#	2.database/02.Datos_prueba.sql
This commit is contained in:
Roberto Orden Erena
2019-12-26 12:25:32 +01:00
32 changed files with 946 additions and 201 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

@@ -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

@@ -6,7 +6,6 @@
<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-2 ui-md-2">
@@ -20,7 +19,7 @@
</p:themeSwitcher>
</div>
<div class="ui-g-2 ui-md-2">
<p:commandButton value="Usar tema en este sesión" update="mesgs" action="#{sessionPreferences.updateCurrentTheme}" icon="pi pi-save" />
<p:commandButton value="Usar tema en este sesión" update="messages" action="#{sessionPreferences.updateCurrentTheme}" icon="pi pi-save" />
</div>
<div class="ui-g-5 ui-md-5" />

View File

@@ -6,9 +6,9 @@
<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: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"/>
@@ -23,39 +23,44 @@
<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="mesgsEdit 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="mesgsEdit frmEditSpecialties" action="#{ManageSpecialities.deleteData}" icon="fa fa-remove" />
</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>
<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,92 @@
<?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="visitForm">
<p:messages 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:calendar id="fecha" value="#{AddVisit.date}" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la visita." />
</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:calendar id="hora" value="#{AddVisit.time}" pattern="HH:mm" showButtonPanel="true" autocomplete="true" required="true" requiredMessage="Especifique la hora de la visita." />
</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-2">
<p:outputLabel for="resultado" value="Resultado:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="resultado" value="#{AddVisit.result}" />
</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="#{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,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="frmPatientVisitList">
<p:messages 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-2">
<div class="ui-inputgroup">
<p:calendar id="fecha" value="#{PatientVisitList.selectedDate}" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" />
<p:commandButton value="Mostrar" update="frmPatientVisitList" action="#{PatientVisitList.showData}" icon="fa calendar-alt" />
</div>
</div>
<div class="ui-g-3">
<p:message for="fecha" display="text" />
</div>
<div class="ui-g-5">
Paciente: <h:outputText value="#{PatientVisitList.patient.displayName}" style="font-weight: bold;" />
</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="date" pattern="dd/MM/yyyy" timeStyle="short" />
</h:outputText>
</p:column>
<p:column headerText="Hora" width="60">
<h:outputText value="#{v.time}">
<f:convertDateTime type="time" 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="Editar" width="90">
<p:commandButton value="Editar" 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-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Consultar" update="frmPatientVisitList" action="#{PatientVisitList.showData}" 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

@@ -8,35 +8,40 @@
<ui:define name="content">
<h:form id="frmVisitList">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Pagina en construcción de Visitas">
<p:panel id="PanelUnderConstruction" header="Consultar agenda del día">
<div class="ui-g ui-fluid">
<div class="ui-g-3">
<div class="ui-g-2">
<p:outputLabel for="fecha" value="Ver agenda del día:" />
</div>
<div class="ui-g-3">
<div class="ui-g-2">
<div class="ui-inputgroup">
<p:calendar id="fecha" value="#{VisitList.selectedDate}" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" />
<p:commandButton value="Consultar" onclick="dtVisitList.getPaginator().setPage(0);"/>
<p:calendar id="fecha" value="#{VisitList.selectedDate}" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" required="true"
requiredMessage="Especifique una fecha para realizar la consulta." />
<p:commandButton value="Mostrar" update="frmVisitList" action="#{VisitList.showData}" icon="fa calendar-alt" />
</div>
</div>
<div class="ui-g-7">
<div class="ui-g-3">
<p:message for="fecha" display="text" />
</div>
<div class="ui-g-5">
Médico de familia: <h:outputText value="#{VisitList.familyDoctorDisplayName}" style="font-weight: bold;" />
</div>
<p:dataTable widgetVar="dtVisitList" var="v" value="#{VisitList.lazyDataModelVisitList}" lazy="true" paginator="true" rows="10" paginatorPosition="bottom"
<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">
<p:column headerText="Id" width="60px;">
<h:outputText value="#{v.id}" />
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="date" pattern="dd/MM/yyyy" timeStyle="short" />
</h:outputText>
</p:column>
<p:column headerText="Fecha" width="auto">
<h:outputText value="#{v.date}" />
</p:column>
<p:column headerText="Hora" width="auto">
<h:outputText value="#{v.time}" />
<p:column headerText="Hora" width="60">
<h:outputText value="#{v.time}">
<f:convertDateTime type="time" pattern="HH:mm" />
</h:outputText>
</p:column>
<p:column headerText="Paciente" width="auto">
@@ -52,18 +57,18 @@
</p:column>
<p:column headerText="Acción" width="80px;">
<p:commandButton value="Ver" action="showVisit" icon="pi pi-check" />
<p:commandButton value="Ver" action="#{VisitList.showVisit(v.id)}" icon="pi pi-check" />
</p:column>
<f:facet name="paginatorBottomLeft">
<p:commandButton type="button" action="#{VisitList.showData}" icon="pi pi-refresh" onclick="PF('dtVisitList').getPaginator().setPage(0);" />
<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-4" />
<div class="ui-g-2 ui-md-2 ">
<p:commandButton validateClient="true" value="Consultar" update="frmVisitList" action="#{VisitList.consultar}" icon="pi pi-check" />
<p:commandButton validateClient="true" value="Consultar" update="frmVisitList" action="#{VisitList.showData}" 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

@@ -4,56 +4,81 @@
<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">
<f:viewParam name="id" value="#{VisitView.id}" required="true" />
<ui:composition template="../header.xhtml">
<ui:define name="content">
<h:form id="TestForm">
<h:form id="visitForm">
<p:messages id="mesgs" showDetail="true" closable="true" autoupdate="true" />
<p:panel id="PanelUnderConstruction" header="Pagina en construcción de Visitas">
<p:panel id="panelVisit" header="Detalles de la visita">
<div class="ui-g ui-fluid">
<div class="ui-g-3">
<p:outputLabel for="campo" value="Ver agenda del día:" />
<div class="ui-g-2">
<p:outputLabel for="paciente" value="Paciente:" />
</div>
<div class="ui-g-3">
<div class="ui-g-8">
<p:inputText id="paciente" value="#{VisitView.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="#{VisitView.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:calendar id="campo" value="" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" />
<p:commandButton value="Fecha" />
<p:calendar id="fecha" value="#{VisitView.date}" pattern="dd/MM/yyyy" showButtonPanel="true" autocomplete="true" required="true"
requiredMessage="Especifique la fecha de la visita." />
</div>
</div>
<div class="ui-g-7">
<p:message for="campo" display="text" />
<div class="ui-g-8">
<p:message for="fecha" 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>
<div class="ui-g-2">
<p:outputLabel for="hora" value="Hora:" />
</div>
<div class="ui-g-2">
<p:calendar id="hora" value="#{VisitView.time}" pattern="HH:mm" showButtonPanel="true" autocomplete="true" required="true" requiredMessage="Especifique la hora de la visita." />
</div>
<div class="ui-g-8">
<p:message for="hora" display="text" />
</div>
<p:column headerText="Title" width="auto">
<h:outputText value="#{qs.title}"/>
</p:column>
<div class="ui-g-2">
<p:outputLabel for="observaciones" value="Observaciones:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="observaciones" value="#{VisitView.observations}" />
</div>
<div class="ui-g-2">
<p:message for="observaciones" display="text" />
</div>
<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-2">
<p:outputLabel for="resultado" value="Resultado:" />
</div>
<div class="ui-g-8">
<p:inputTextarea id="resultado" value="#{VisitView.result}" />
</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 validateClient="true" value="Guardar" update="visitForm" action="#{VisitView.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

@@ -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

@@ -481,19 +481,19 @@ public class CommonFacadeBean implements CommonFacadeRemote, CommonFacadeLocal {
return qsTO;
}
public VisitTO getPOJOforVisitJPA(VisitJPA qs, int nestedProps) {
public VisitTO getPOJOforVisitJPA(VisitJPA vi, int nestedProps) {
VisitTO qsTO = null;
if (qs != null) {
if (vi != null) {
FamilyDoctorJPA fd = null;
PatientJPA pat = null;
if (nestedProps > 0) {
fd = qs.getFamilyDoctor();
pat = qs.getPatient();
fd = vi.getFamilyDoctor();
pat = vi.getPatient();
}
nestedProps--;
qsTO = new VisitTO(qs.getId(), qs.getDate(), qs.getTime(), qs.getObservations(), qs.getResult(), this.getPOJOforFamilyDoctorJPA(fd, nestedProps),
qsTO = new VisitTO(vi.getId(), vi.getDate(), vi.getTime(), vi.getObservations(), vi.getResult(), this.getPOJOforFamilyDoctorJPA(fd, nestedProps),
this.getPOJOforPatientJPA(pat, nestedProps));
}

View File

@@ -1,9 +1,12 @@
package ejb.systemAdmin;
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;
@@ -33,29 +36,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 +62,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 +70,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 +90,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 +108,7 @@ public class SystemAdminFacadeBean implements SystemAdminFacadeRemote {
}
@Override
public MedicalSpecialtyTO updateSpecialtyData(int id, String name, String description) throws Exception {
public MedicalSpecialtyTO getSpecialty(int id, String name, String description) throws Exception {
MedicalSpecialtyJPA ms = entman.find(MedicalSpecialtyJPA.class, id);
if (ms == null) {
@@ -126,8 +123,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, String name, String description) throws Exception {
MedicalSpecialtyJPA ms = entman.find(MedicalSpecialtyJPA.class, id);
if (ms == null) {
@@ -138,7 +147,7 @@ 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);

View File

@@ -4,6 +4,7 @@ import javax.ejb.Remote;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import TO.PatientTO;
/**
*
@@ -18,9 +19,11 @@ public interface SystemAdminFacadeRemote {
public LoggedUserTO login(String id, String pwd);
public MedicalSpecialtyTO updateSpecialtyData(int id, String name, String description) throws Exception;
public MedicalSpecialtyTO getSpecialty(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, String name, String description) throws Exception;
public MedicalSpecialtyTO insertSpecialty(String name, String description) throws Exception;
}

View File

@@ -11,9 +11,14 @@ import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import TO.VisitTO;
import common.HashUtils;
import common.QuestionStatus;
import common.Utils;
import ejb.common.CommonFacadeLocal;
import jpa.FamilyDoctorJPA;
import jpa.MedicalSpecialtyJPA;
import jpa.QuestionJPA;
import jpa.SpecialistDoctorJPA;
import jpa.VisitJPA;
/**
@@ -60,4 +65,69 @@ public class VisitFacadeBean implements VisitFacadeRemote {
return listTO;
}
public Long getVisitsCount(Integer patientId, Date 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) {
strQuery = String.format(strQuery, "WHERE 1=1 " + 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, Date 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) {
strQuery = String.format(strQuery, "WHERE 1=1 " + 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);
}
}

View File

@@ -22,4 +22,10 @@ public interface VisitFacadeRemote {
public Long getScheduledVisitsCount(int familyDoctorId, Date date);
public List<VisitTO> listAllScheduledVisitsPaged(int familyDoctorId, Date date, int pageNumber, int pageSize);
public Long getVisitsCount(Integer patientId, Date date);
public List<VisitTO> listVisitsPaged(Integer patientId, Date date, int pageNumber, int pageSize);
public VisitTO getVisit(int id) throws Exception;
}

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,31 @@ 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);
}
}
ses = req.getSession(false);
// Para recursos publicos permitimos el acceso exista sesión o no.
@@ -85,7 +105,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,7 +117,7 @@ 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/Questions") > 0)
authorized = true;

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

@@ -56,13 +56,13 @@ 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/VisitList", null));

View File

@@ -38,7 +38,13 @@ public class SessionUtils {
}
public static void createOrUpdateSession(LoggedUserTO usr) {
HttpSession ses = getSession(true);
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());
@@ -77,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

@@ -100,6 +100,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;
}
}
@@ -300,19 +301,19 @@ public class UpdateProfileMBean extends ManagedBeanBase implements Serializable
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);
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);
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);
usr = new LoggedUserTO(sd.getId().toString(), sd.getName(), sd.getPassword(), this.userType, sd.getDisplayName());
break;
case ADMINISTRATOR:

View File

@@ -3,6 +3,7 @@ package managedbean.systemAdmin;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import javax.servlet.http.HttpSession;
import org.primefaces.PrimeFaces;
@@ -50,18 +51,36 @@ public class LoginMBean extends ManagedBeanBase {
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");

View File

@@ -7,12 +7,14 @@ import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import javax.persistence.PersistenceException;
import TO.LoggedUserTO;
import TO.MedicalSpecialtyTO;
import common.Constants;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
import managedbean.common.ValidationUtils;
@Named("ManageSpecialities")
@RequestScoped
@@ -95,20 +97,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());
MedicalSpecialtyTO ms = this.getRemoteManagerSystemAdmin().getSpecialty(this.medicalSpecialty.getId(), this.medicalSpecialty.getName(), this.medicalSpecialty.getDescription());
this.setSpecialtyData(ms);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de la especialidad se han guardado correctamente.");
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
} catch (Exception e) {
this.manageException(e);
}
@@ -129,8 +132,9 @@ public class ManageSpecialitiesMBean extends ManagedBeanBase implements Serializ
if (error == 0) {
try {
this.getRemoteManagerSystemAdmin().deleteSpecialtyData(this.medicalSpecialty.getId(), this.medicalSpecialty.getName(), this.medicalSpecialty.getDescription());
this.getRemoteManagerSystemAdmin().deleteSpecialty(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.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
} catch (Exception e) {
this.manageException(e);
}
@@ -149,11 +153,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);
MedicalSpecialtyTO ms = this.getRemoteManagerSystemAdmin().insertSpecialty(name, description);
this.setSpecialtyData(ms);
this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de la especialidad se han guardado correctamente.");
this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH);
} catch (Exception e) {
this.manageException(e);
}

View File

@@ -0,0 +1,122 @@
package managedbean.visit;
import java.io.Serializable;
import java.sql.Time;
import java.util.Date;
import java.util.List;
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.inject.Named;
import org.primefaces.model.LazyDataModel;
import org.primefaces.model.SortOrder;
import TO.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("AddVisit")
@RequestScoped
public class AddVisitMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Date date;
private Time 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
Integer patientId = Integer.valueOf(SessionUtils.getUserId());
this.patient = this.getRemoteManagerCommon().findPatientById(patientId);
this.familyDoctor = this.patient.getFamilyDoctor();
this.date = new Date();
}
public void saveData() {
// TODO: Añadir la nueva visita a la BBDD
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Time getTime() {
return time;
}
public void setTime(Time 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,106 @@
package managedbean.visit;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
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.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
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 Date selectedDate;
public PatientVisitListMBean() {
}
@PostConstruct
public void init() {
// 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.setPatient(null);
this.selectedDate = new Date();
break;
case PATIENT:
this.patientId = Integer.valueOf(SessionUtils.getUserId());
this.setPatient(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) {
Long totalRowCount = getRemoteManagerVisit().getVisitsCount(patientId, selectedDate);
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerVisit().listVisitsPaged(patientId, selectedDate, (first / pageSize), pageSize);
}
};
}
public void removeVisit(Integer visitId) throws IOException {
// TODO: Eliminar visita de la BBDD
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.getCurrentInstance().getExternalContext().redirect("VisitView.xhtml?id=" + visitId.toString());
}
public LazyDataModel<VisitTO> getLazyDataModelVisitList() {
return lazyDataModelVisitList;
}
public void showData() {
}
public Date getSelectedDate() {
return selectedDate;
}
public void setSelectedDate(Date selectedDate) {
this.selectedDate = selectedDate;
}
public PatientTO getPatient() {
return patient;
}
public void setPatient(PatientTO patient) {
this.patient = patient;
}
}

View File

@@ -1,12 +1,14 @@
package managedbean.visit;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.model.LazyDataModel;
@@ -17,12 +19,13 @@ import managedbean.common.ManagedBeanBase;
import managedbean.common.SessionUtils;
@Named("VisitList")
@RequestScoped
@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 Date selectedDate;
@@ -33,6 +36,8 @@ public class VisitListMBean extends ManagedBeanBase implements Serializable {
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 = new Date();
this.lazyDataModelVisitList = new LazyDataModel<VisitTO>() {
@@ -40,7 +45,7 @@ public class VisitListMBean extends ManagedBeanBase implements Serializable {
@Override
public List<VisitTO> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
Long totalRowCount = getRemoteManagerMedicalTest().getPendingQuestionsCount(familyDoctorId);
Long totalRowCount = getRemoteManagerVisit().getScheduledVisitsCount(familyDoctorId, selectedDate);
this.setRowCount(totalRowCount.intValue());
return getRemoteManagerVisit().listAllScheduledVisitsPaged(familyDoctorId, selectedDate, (first / pageSize), pageSize);
@@ -52,12 +57,11 @@ public class VisitListMBean extends ManagedBeanBase implements Serializable {
return lazyDataModelVisitList;
}
public void saveData() {
public void showData() {
}
public void showData() {
public void showVisit(Integer visitId) throws IOException {
FacesContext.getCurrentInstance().getExternalContext().redirect("VisitView.xhtml?id=" + visitId.toString());
}
public Date getSelectedDate() {
@@ -67,4 +71,8 @@ public class VisitListMBean extends ManagedBeanBase implements Serializable {
public void setSelectedDate(Date selectedDate) {
this.selectedDate = selectedDate;
}
public String getFamilyDoctorDisplayName() {
return familyDoctorDisplayName;
}
}

View File

@@ -1,28 +1,126 @@
package managedbean.visit;
import java.io.Serializable;
import java.sql.Time;
import java.util.Date;
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.inject.Named;
import TO.FamilyDoctorTO;
import TO.PatientTO;
import TO.VisitTO;
import managedbean.common.ManagedBeanBase;
@Named("VisitMBean")
@Named("VisitView")
@RequestScoped
public class VisitMBean extends ManagedBeanBase implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Date date;
private Time time;
private String observations;
private String result;
private PatientTO patient;
private FamilyDoctorTO familyDoctor;
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 {
// Parámetro con el "name" de la especialidad a editar.
int id = Integer.valueOf(requestParams.get("id").toString());
vi = this.getRemoteManagerVisit().getVisit(id);
} catch (Exception e) {
this.manageException(e);
}
if (vi != null) {
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 saveData() {
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Time getTime() {
return time;
}
public void setTime(Time 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;
}
}

View File

@@ -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;

View File

@@ -106,52 +106,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);
INSERT INTO myhealth.medicaltest(date, "time", observations, highresimage,"type",patientid, specialistdoctorid) VALUES
('2019/12/15',now(),'',null,0,1,1),
('2019/12/15',now(),'',null,0,1,2),
('2019/12/15',now(),'',null,0,2,1);
-- Insertar datos de prueba para visitas
INSERT INTO myhealth.visit(date, "time", observations, result, patientid, familydoctorid) VALUES
('23/12/2019','09:00','Observaciones de la visita 43822','',1,1),
('23/12/2019','10:00','Observaciones de la visita 43822','',2,1),
('23/12/2019','11:00','Observaciones de la visita 43822','',3,1),
('23/12/2019','12:00','Observaciones de la visita 43822','',4,1),
('23/12/2019','13:00','Observaciones de la visita 43822','',5,1),
('23/12/2019','14:00','Observaciones de la visita 43822','',6,1),
('23/12/2019','15:00','Observaciones de la visita 43822','',7,1),
('23/12/2019','16:00','Observaciones de la visita 43822','',8,1),
('23/12/2019','17:00','Observaciones de la visita 43822','',9,1),
('23/12/2019','18:00','Observaciones de la visita 43822','',10,1),
('24/12/2019','09:00','Observaciones de la visita 43823','',1,1),
('25/12/2019','10:00','Observaciones de la visita 43824','',2,1),
('26/12/2019','11:00','Observaciones de la visita 43825','',3,1),
('27/12/2019','12:00','Observaciones de la visita 43826','',4,1),
('28/12/2019','13:00','Observaciones de la visita 43827','',5,1),
('29/12/2019','14:00','Observaciones de la visita 43828','',6,1),
('30/12/2019','15:00','Observaciones de la visita 43829','',7,1),
('31/12/2019','16:00','Observaciones de la visita 43830','',8,1),
('01/01/2020','17:00','Observaciones de la visita 43831','',9,1),
('02/01/2020','18:00','Observaciones de la visita 43832','',10,1),
('23/12/2019','09:00','Observaciones de la visita 43822','',1,2),
('23/12/2019','10:00','Observaciones de la visita 43822','',2,2),
('23/12/2019','11:00','Observaciones de la visita 43822','',3,2),
('23/12/2019','12:00','Observaciones de la visita 43822','',4,2),
('23/12/2019','13:00','Observaciones de la visita 43822','',5,2),
('23/12/2019','14:00','Observaciones de la visita 43822','',6,2),
('23/12/2019','15:00','Observaciones de la visita 43822','',7,2),
('23/12/2019','16:00','Observaciones de la visita 43822','',8,2),
('23/12/2019','17:00','Observaciones de la visita 43822','',9,2),
('23/12/2019','18:00','Observaciones de la visita 43822','',10,2),
('24/12/2019','09:00','Observaciones de la visita 43823','',1,2),
('25/12/2019','10:00','Observaciones de la visita 43824','',2,2),
('26/12/2019','11:00','Observaciones de la visita 43825','',3,2),
('27/12/2019','12:00','Observaciones de la visita 43826','',4,2),
('28/12/2019','13:00','Observaciones de la visita 43827','',5,2),
('29/12/2019','14:00','Observaciones de la visita 43828','',6,2),
('30/12/2019','15:00','Observaciones de la visita 43829','',7,2),
('31/12/2019','16:00','Observaciones de la visita 43830','',8,2),
('01/01/2020','17:00','Observaciones de la visita 43831','',9,2),
('02/01/2020','18:00','Observaciones de la visita 43832','',10,2);
('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', 'Radiografía Tórax', 1, 1),
('2019-12-24','19:20:00','Observaciones del medical test2','somehighresimage2', 'TAC Craneal', 2, 1),
('2019-12-25','18:35:20','Observaciones del medical test3','somehighresimage3', 'Radiografía Cadera', 3, 2),
('2019-12-26','08:15:10','Observaciones del medical test4','somehighresimage4', 'TAC Rodilla', 4, 2),
('2019-12-27','18:15:10','Observaciones del medical test5','somehighresimage5', 'TAC Pie Izquierdo', 5, 1),
('2019-12-28','22:15:40','Observaciones del medical test6','somehighresimage6', 'Radiografía Tórax', 6, 3),
('2019-12-28','23:15:40','Observaciones del medical test7','somehighresimage7', 'Radiografía Tibia', 7, 1),
('2019-12-29','11:12:20','Observaciones del medical test8','somehighresimage8', 'TAC Craneal', 8, 1),
('2019-12-30','13:17:50','Observaciones del medical test9','somehighresimage9', 'Radiografía Cadera', 2, 2),
('2019-12-31','05:08:30','Observaciones del medical test10','somehighresimage10', 'Radiografía rodilla', 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

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,7 +24,29 @@ 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