From 20e6ccd1849096aea723c7b46e8e26251b78df48 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Sun, 29 Dec 2019 19:43:54 +0100 Subject: [PATCH 1/6] doc: tests basicos de cobertura de funcionalidades por componente --- ...Practica_4_Grupo_2_Informe de testing.docx | Bin 733200 -> 736930 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/3.docs/PDS_Practica_4_Grupo_2_Informe de testing.docx b/3.docs/PDS_Practica_4_Grupo_2_Informe de testing.docx index 5347cbde7d6cdcb0033236863d9031fd3978a5df..edb215fd72bf23a438387b4df7988a374876ec28 100644 GIT binary patch delta 24197 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 Date: Sun, 29 Dec 2019 21:01:23 +0100 Subject: [PATCH 2/6] =?UTF-8?q?Di=C3=A1logo=20confirmaci=C3=B3n=20eliminac?= =?UTF-8?q?i=C3=B3n=20CAP=20coherente=20con=20resto=20sistema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docroot/systemAdmin/ManageHealthCareCenters.xhtml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/1.sources/MyHealth/docroot/systemAdmin/ManageHealthCareCenters.xhtml b/1.sources/MyHealth/docroot/systemAdmin/ManageHealthCareCenters.xhtml index 110763e..29c6ff6 100644 --- a/1.sources/MyHealth/docroot/systemAdmin/ManageHealthCareCenters.xhtml +++ b/1.sources/MyHealth/docroot/systemAdmin/ManageHealthCareCenters.xhtml @@ -35,15 +35,20 @@ - - - + + + + + + + + From b6e4116d0fc5f45e2e0817fc8cd7e41b279b3e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garcia=20Nu=C3=B1ez?= Date: Sun, 29 Dec 2019 21:33:57 +0100 Subject: [PATCH 3/6] =?UTF-8?q?Mejoras=20en=20la=20gesti=C3=B3n=20de=20pru?= =?UTF-8?q?ebas=20m=C3=A9dicas=20(filtros=20de=20b=C3=BAsqueda)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docroot/medicaltest/MedicalTests.xhtml | 188 +++++++++------ .../medicalTest/MedicalTestFacadeBean.java | 153 ++++++------ .../medicalTest/MedicalTestFacadeRemote.java | 27 +-- .../MyHealth/src/jpa/MedicalTestJPA.java | 3 +- .../medicalTest/MedicalTestMBean.java | 228 ++++++++++-------- 5 files changed, 341 insertions(+), 258 deletions(-) diff --git a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml index 7218dc2..7c8c48e 100644 --- a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml +++ b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml @@ -1,10 +1,7 @@ - @@ -15,33 +12,41 @@ - + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
- +
@@ -49,76 +54,109 @@
- + + + + + +
-
Fecha:
-
- +
Fecha:
+
+
-
Hora:
-
- +
Hora:
+
+
-
Observaciones:
-
- +
Observaciones:
+
+
-
Tipo de prueba:
-
- +
Tipo de prueba:
+
+
-
Imagen de alta resolución:
-
-
- - -
-
- -
-
- -
+
+ +
+
Imagen de alta resolución:
+
+ +
+
+ +
+
+ + + +
+
+ +
+
+
- + +
-
Fecha:
-
- +
Paciente:
+
+ + + + + + + + + + + +
-
Hora:
-
- + +
Fecha:
+
+
-
Observaciones:
-
- + +
Hora:
+
+ + +
-
Tipo de prueba:
-
- - + +
Observaciones:
+
+ +
+ +
Tipo de prueba:
+
+ +
-
-
- +
+
+
-
- +
diff --git a/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeBean.java b/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeBean.java index c3981df..d4664fe 100644 --- a/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeBean.java +++ b/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeBean.java @@ -17,6 +17,7 @@ import TO.QuestionTO; import TO.SpecialistDoctorTO; import common.MedicalTestType; import common.QuestionStatus; +import common.Utils; import ejb.common.CommonFacadeLocal; import jpa.MedicalTestJPA; import jpa.PatientJPA; @@ -24,12 +25,10 @@ import jpa.QuestionJPA; 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 * @@ -96,9 +95,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { // TypedQuery query = entman.createQuery("SELECT q from QuestionJPA // q where q.status=:status and q.familyDoctor.id=:docId order by q.title", // QuestionJPA.class); - TypedQuery query = entman.createQuery( - "SELECT q from QuestionJPA q where q.familyDoctor.id=:docId order by q.status desc, q.title asc", - QuestionJPA.class); + TypedQuery 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); @@ -117,9 +114,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { // TypedQuery query = entman.createQuery("SELECT q from QuestionJPA // q where q.status=:status and q.familyDoctor.id=:docId order by q.title", // QuestionJPA.class); - TypedQuery query = entman.createQuery( - "SELECT q from QuestionJPA q where q.patient.id=:patientId order by q.status desc, q.title asc", - QuestionJPA.class); + TypedQuery 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); @@ -140,8 +135,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { public QuestionTO getQuestion(int idQuestion) { QuestionTO resp = new QuestionTO(); - TypedQuery query = entman.createQuery("SELECT q from QuestionJPA q where q.id=:idquestion", - QuestionJPA.class); + TypedQuery query = entman.createQuery("SELECT q from QuestionJPA q where q.id=:idquestion", QuestionJPA.class); query.setParameter("idquestion", idQuestion); @@ -156,29 +150,23 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { /** * Añadir pruebas médicas a una cita * - * Dado que será añadida por el médico especialista en sesión no hace falta más - * información. + * Dado que será añadida por el médico especialista en sesión no hace falta más información. * * @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 */ - public String addMedicalTest(int patientID, int doctorSpecialistID, Date date, LocalTime time, - MedicalTestType testType, String observations) { - try { - SpecialistDoctorJPA specDoctor = entman.find(SpecialistDoctorJPA.class, doctorSpecialistID); - PatientJPA pat = entman.find(PatientJPA.class, patientID); + public MedicalTestTO addMedicalTest(int patientID, int doctorSpecialistID, Date 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(0, date, time, observations, null, testType, pat, specDoctor); + MedicalTestJPA mt = new MedicalTestJPA(date, time, observations, null, testType, pat, specDoctor); - entman.persist(mt); - return "ok"; - } catch (Exception ex) { - return ex.getMessage(); - } + entman.persist(mt); + + return this.commonServices.getPOJOforMedicalTestJPA(mt, 1); } /** @@ -197,8 +185,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { } private MedicalTestJPA getMedicalTestJPA(int idMedicalTest) { - TypedQuery query = entman - .createQuery("SELECT q from MedicalTestJPA q where q.id=:idMedicalTest", MedicalTestJPA.class); + TypedQuery query = entman.createQuery("SELECT q from MedicalTestJPA q where q.id=:idMedicalTest", MedicalTestJPA.class); query.setParameter("idMedicalTest", idMedicalTest); return query.getSingleResult(); } @@ -239,8 +226,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { } public Long getSpecialistDoctorByMedicalSpecialityCount(int specialityId) { - TypedQuery query = entman.createQuery( - "SELECT count(1) from SpecialistDoctorJPA q where q.medicalSpecialty.id=:specId", Long.class); + TypedQuery query = entman.createQuery("SELECT count(1) from SpecialistDoctorJPA q where q.medicalSpecialty.id=:specId", Long.class); query.setParameter("specId", specialityId); return query.getSingleResult(); @@ -251,13 +237,11 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { * * @param speciality */ - public List findSpecialistDoctorByMedicalSpeciality(int specialityId, int pageNumber, - int pageSize) { + public List findSpecialistDoctorByMedicalSpeciality(int specialityId, int pageNumber, int pageSize) { List pendingQuestions = new ArrayList(); TypedQuery query = entman.createQuery( - "SELECT q from SpecialistDoctorJPA q where q.medicalSpecialty.id=:specId order by q.medicalSpecialty.name asc, q.surname asc", - SpecialistDoctorJPA.class); + "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) { @@ -278,9 +262,7 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { public List loadMedicalTestForPatient(int patientID) { List medicalTests = new ArrayList(); - TypedQuery query = entman.createQuery( - "SELECT q from MedicalTestJPA q where q.patient.id=:patientId order by q.id desc", - MedicalTestJPA.class); + TypedQuery query = entman.createQuery("SELECT q from MedicalTestJPA q where q.patient.id=:patientId order by q.id desc", MedicalTestJPA.class); query.setParameter("patientId", patientID); @@ -304,18 +286,17 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { } @Override - public List loadMedicalTestForFamilyDoctor(int familyDoctorID, int patientID) { + public List loadMedicalTestForFamilyDoctor(int familyDoctorID, Integer patientID) { List medicalTests = new ArrayList(); String extraQuery = ""; - if (patientID > 0) { + if (patientID != null) { extraQuery = " and q.patient.id=:patientID"; } TypedQuery 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) { + .createQuery("SELECT q from MedicalTestJPA q where q.patient.familyDoctor.id=:familyDoctorID " + extraQuery + " order by q.id desc", MedicalTestJPA.class); + if (patientID != null) { query.setParameter("patientID", patientID); } query.setParameter("familyDoctorID", familyDoctorID); @@ -330,19 +311,18 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { } @Override - public List loadMedicalTestForSpecialistDoctor(int specialistDoctorID, int patientID) { + public List loadMedicalTestForSpecialistDoctor(int specialistDoctorID, Integer patientID) { List medicalTests = new ArrayList(); String extraQuery = ""; - if (patientID > 0) { + if (patientID != null) { extraQuery = " and q.patient.id=:patientID"; } TypedQuery query = entman - .createQuery("SELECT q from MedicalTestJPA q where q.specialistDoctor.id=:specialistDoctorID " - + extraQuery + " order by q.id desc", MedicalTestJPA.class); + .createQuery("SELECT q from MedicalTestJPA q where q.specialistDoctor.id=:specialistDoctorID " + extraQuery + " order by q.id desc", MedicalTestJPA.class); - if (patientID > 0) { + if (patientID != null) { query.setParameter("patientID", patientID); } query.setParameter("specialistDoctorID", specialistDoctorID); @@ -356,42 +336,73 @@ public class MedicalTestFacadeBean implements MedicalTestFacadeRemote { return medicalTests; } - @Override - public List loadPatientsForSpecialistDoctor(int specialistDoctorID) { - List medicalTests = new ArrayList(); + public List 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); - TypedQuery query = entman.createQuery( - "SELECT distinct q.patient from MedicalTestJPA q where q.specialistDoctor.id=:specialistDoctorID", - PatientJPA.class); + if (searchTerm.length() > 0) { + strFilter = "and lower(q.patient.name) LIKE :searchTerm OR lower(q.patient.surname) LIKE :searchTerm"; + } + + TypedQuery query = entman.createQuery(String.format(strQuery, strFilter), PatientJPA.class); + + if (searchTerm.length() > 0) + query.setParameter("searchTerm", "%" + searchTerm + "%"); query.setParameter("specialistDoctorID", specialistDoctorID); - List allJPA = query.getResultList(); - - for (PatientJPA item : allJPA) { - medicalTests.add(commonServices.getPOJOforPatientJPA(item, 1)); + if (pageSize > 0) { + query.setFirstResult(pageNumber * pageSize); + query.setMaxResults(pageSize); } - return medicalTests; + List allJPA = query.getResultList(); + List patsTO = new ArrayList(); + + for (PatientJPA item : allJPA) { + patsTO.add(commonServices.getPOJOforPatientJPA(item, 1)); + } + + return patsTO; } - @Override - public List loadPatientsForFamilyDoctor(int familyDoctorID) { - List medicalTests = new ArrayList(); + public List 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"; - TypedQuery query = entman.createQuery( - "SELECT distinct q.patient from MedicalTestJPA q where q.patient.familyDoctor.id=:familyDoctorID", - PatientJPA.class); + 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 query = entman.createQuery(String.format(strQuery, strFilter), PatientJPA.class); + + if (searchTerm.length() > 0) + query.setParameter("searchTerm", "%" + searchTerm + "%"); query.setParameter("familyDoctorID", familyDoctorID); - List allJPA = query.getResultList(); - - for (PatientJPA item : allJPA) { - medicalTests.add(commonServices.getPOJOforPatientJPA(item, 1)); + if (pageSize > 0) { + query.setFirstResult(pageNumber * pageSize); + query.setMaxResults(pageSize); } - return medicalTests; + List allJPA = query.getResultList(); + List patsTO = new ArrayList(); + + for (PatientJPA item : allJPA) { + patsTO.add(commonServices.getPOJOforPatientJPA(item, 1)); + } + + return patsTO; } } \ No newline at end of file diff --git a/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeRemote.java b/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeRemote.java index 60b3063..a8b3202 100644 --- a/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeRemote.java +++ b/1.sources/MyHealth/src/ejb/medicalTest/MedicalTestFacadeRemote.java @@ -66,22 +66,21 @@ public interface MedicalTestFacadeRemote { // TEST public List loadMedicalTestForPatient(int patientID); - + public List loadMedicalTestForFamilyDoctor(int familyDoctorID); - + public List loadMedicalTestForSpecialistDoctor(int specialistDoctorID); - - public List loadMedicalTestForFamilyDoctor(int familyDoctorID, int patientID); - - public List loadMedicalTestForSpecialistDoctor(int specialistDoctorID, int patientID); - - public List loadPatientsForSpecialistDoctor(int specialistDoctorID); - - public List loadPatientsForFamilyDoctor(int familyDoctorID); - + + public List loadMedicalTestForFamilyDoctor(int familyDoctorID, Integer patientID); + + public List loadMedicalTestForSpecialistDoctor(int specialistDoctorID, Integer patientID); + + public List loadPatientsForSpecialistDoctor(int specialistDoctorID, String searchTerm, int pageNumber, int pageSize); + + public List loadPatientsForFamilyDoctor(int familyDoctorID, String searchTerm, int pageNumber, int pageSize); + /** - * 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. + * 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 @@ -89,7 +88,7 @@ public interface MedicalTestFacadeRemote { * @param testType Pudiera llegar a ser: Análisis de sangre, resonancias magnéticas y TAC * @param observations */ - public String addMedicalTest(int patientID, int doctorSpecialistID, Date date, LocalTime time, MedicalTestType testType, String observations); + public MedicalTestTO addMedicalTest(int patientID, int doctorSpecialistID, Date date, LocalTime time, MedicalTestType testType, String observations) throws Exception; /** * Recuperar una prueba médica por ID diff --git a/1.sources/MyHealth/src/jpa/MedicalTestJPA.java b/1.sources/MyHealth/src/jpa/MedicalTestJPA.java index 616205b..fa06fa0 100644 --- a/1.sources/MyHealth/src/jpa/MedicalTestJPA.java +++ b/1.sources/MyHealth/src/jpa/MedicalTestJPA.java @@ -57,8 +57,7 @@ public class MedicalTestJPA implements Serializable { super(); } - public MedicalTestJPA(int id, Date date, LocalTime time, String observations, String highresimage, MedicalTestType type, PatientJPA patient, SpecialistDoctorJPA specialistDoctor) { - this.id = id; + public MedicalTestJPA(Date date, LocalTime time, String observations, String highresimage, MedicalTestType type, PatientJPA patient, SpecialistDoctorJPA specialistDoctor) { this.date = date; this.time = time; this.observations = observations; diff --git a/1.sources/MyHealth/src/managedbean/medicalTest/MedicalTestMBean.java b/1.sources/MyHealth/src/managedbean/medicalTest/MedicalTestMBean.java index 1ed7e98..71e7503 100644 --- a/1.sources/MyHealth/src/managedbean/medicalTest/MedicalTestMBean.java +++ b/1.sources/MyHealth/src/managedbean/medicalTest/MedicalTestMBean.java @@ -11,12 +11,12 @@ import javax.faces.event.AjaxBehaviorEvent; import javax.faces.view.ViewScoped; import javax.inject.Named; -import org.primefaces.event.FileUploadEvent; import org.primefaces.event.SelectEvent; import org.primefaces.model.UploadedFile; import TO.MedicalTestTO; import TO.PatientTO; +import common.Constants; import common.MedicalTestType; import common.UserType; import managedbean.common.ManagedBeanBase; @@ -33,8 +33,14 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { private List medicalTests; private MedicalTestTO selected; private PatientTO patSelected; + private PatientTO patientFilterSelected; private boolean addNewMode = false; private UploadedFile imageUpload; + private List patientList; + private List patientWithTestList; + private String lastUIQuery; + private String lastUIQueryPatFilter; + private List medicalTestTypes; public MedicalTestMBean() { } @@ -43,34 +49,48 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { public void init() { this.userType = SessionUtils.getUserType(); this.userID = Integer.valueOf(SessionUtils.getUserId()); + this.medicalTestTypes = new ArrayList(); + 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(); - this.getPatients(); - } - - public void addMedicalTest() { - getRemoteManagerMedicalTest().addMedicalTest(this.selected.getPatient().getId(), userID, - this.selected.getDate(), this.selected.getTime(), this.selected.getType(), - this.selected.getObservations()); } 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); + 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"); + } else { + System.out.println("IMAGEN SUBIDA ES NULA"); } } - + public UploadedFile getImageUpload() { return imageUpload; } @@ -102,35 +122,68 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { } public void loadMedicalTests() { - if (userType == UserType.PATIENT) { + Integer patId = null; + 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); - } else if (userType == UserType.SPECIALIST_DOCTOR) { + break; + case SPECIALIST_DOCTOR: // Cargar las pruebas que el doctor especialista ha creado - this.medicalTests = getRemoteManagerMedicalTest().loadMedicalTestForSpecialistDoctor(userID, - this.patIdSelected); - } else if (userType == UserType.FAMILY_DOCTOR) { + 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, - this.patIdSelected); - } else { - // Nothing todo - this.medicalTests = new ArrayList(); - } + 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 getPatients() { - if (userType == UserType.SPECIALIST_DOCTOR) { - // Cargar los pacientes a los que ha añadido pruebas médicas el médico - // especialista - return getRemoteManagerMedicalTest().loadPatientsForSpecialistDoctor(userID); - } else if (userType == UserType.FAMILY_DOCTOR) { - // Cargar los pacientes del médico de familia que tiene pruebas médicas hechas - return getRemoteManagerMedicalTest().loadPatientsForFamilyDoctor(userID); - } else { - // Nothing todo - return new ArrayList(); + public List 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 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 getPatientList() { + return patientList; + } + + public List getPatientWithTestList() { + return patientWithTestList; } public List getMedicalTests() { @@ -141,18 +194,6 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { // Nothing to do } - /*************************************************** METODOS PARA LA VISTA */ - private int patIdSelected = -1; - - public void setPatIdSelected(Integer value) { - this.patIdSelected = value; - this.addNewMode = false; - } - - public Integer getPatIdSelected() { - return this.patIdSelected; - } - public boolean isSpecialistDoctor() { return this.userType == UserType.SPECIALIST_DOCTOR; } @@ -161,10 +202,20 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { return !(userType == UserType.PATIENT); } - public void onSelectPatient(AjaxBehaviorEvent event) { + public void clearFilteredPatient() { + 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.loadMedicalTests(); - } public void onSelectMT(SelectEvent event) { @@ -173,16 +224,13 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { } public void addMT() { - if (this.patIdSelected != -1) { - this.selected = new MedicalTestTO(); - this.selected.setId(-1); - this.selected.setObservations(""); - this.selected.setType(MedicalTestType.BLOOD_TEST); - this.addNewMode = true; - } else { - this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Atención!", - "Debe elegir un paciente al que añadir la prueba médica."); - } + // Si hay un paciente filtrado en la busqueda de pruebas, lo seleccionamos para la prueba a añadir. + this.patSelected = this.patientFilterSelected; + this.selected = new MedicalTestTO(); + this.selected.setId(-1); + this.selected.setObservations(""); + this.selected.setType(MedicalTestType.BLOOD_TEST); + this.addNewMode = true; } public boolean isAddNewMode() { @@ -202,44 +250,32 @@ public class MedicalTestMBean extends ManagedBeanBase implements Serializable { } public List getMedicalTestTypes() { - ArrayList list = new ArrayList(); - list.add(MedicalTestType.BLOOD_TEST); - list.add(MedicalTestType.CT_SCAN); - list.add(MedicalTestType.MAGNETIC_RESONANCE_IMAGING); - return list; - } - - public String getMedicalTestTypeSelected() { - return this.selected.getType().getName(); - } - - public void setMedicalTestTypeSelected(String val) { - System.out.println("********************************"); - System.out.println(val); - System.out.println("********************************"); - MedicalTestType mt; - if (val.equals("BLOOD_TEST")) { - mt = MedicalTestType.BLOOD_TEST; - } else if (val.equals("CT_SCAN")) { - mt = MedicalTestType.CT_SCAN; - } else { - mt = MedicalTestType.MAGNETIC_RESONANCE_IMAGING; - } - this.selected.setType(mt); - System.out.println("********************************"); - System.out.println(this.selected.getType()); - System.out.println("********************************"); + return this.medicalTestTypes; } public void save() { - String res = getRemoteManagerMedicalTest().addMedicalTest(this.patIdSelected, userID, this.selected.getDate(), - this.selected.getTime(), this.selected.getType(), this.selected.getObservations()); - if (res.equals("ok")) { - this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Éxito", "Guardado correctamente"); - } else { - this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Error", res); + try { + + MedicalTestTO mt = this.getRemoteManagerMedicalTest().addMedicalTest(this.patSelected.getId(), this.userID, this.selected.getDate(), this.selected.getTime(), + this.selected.getType(), this.selected.getObservations()); + + 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); } - this.loadMedicalTests(); + } + + public PatientTO getPatientFilterSelected() { + return patientFilterSelected; + } + + public void setPatientFilterSelected(PatientTO patientFilterSelected) { + this.patientFilterSelected = patientFilterSelected; } } From d0e41c5d5fda91c8b0604259515824162a6d0eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garcia=20Nu=C3=B1ez?= Date: Sun, 29 Dec 2019 21:43:28 +0100 Subject: [PATCH 4/6] =?UTF-8?q?Correcci=C3=B3n=20de=20error=20en=20la=20vi?= =?UTF-8?q?sta=20de=20paciente=20y=20m=C3=A9dico=20de=20familia.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml index 7c8c48e..93893eb 100644 --- a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml +++ b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml @@ -15,11 +15,11 @@ - + - From ba4a4e123ceb286bf69add49f3779cc2b6d67029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garcia=20Nu=C3=B1ez?= Date: Sun, 29 Dec 2019 21:50:00 +0100 Subject: [PATCH 5/6] Mantiene el elemento seleccionado en la lista de pruebas. --- 1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml index 93893eb..599ce46 100644 --- a/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml +++ b/1.sources/MyHealth/docroot/medicaltest/MedicalTests.xhtml @@ -41,7 +41,7 @@ - + From f80ad15f016bde43f39b38d7737bbe13ebde29b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Garcia=20Nu=C3=B1ez?= Date: Sun, 29 Dec 2019 22:05:26 +0100 Subject: [PATCH 6/6] Centrado de botones. --- 1.sources/MyHealth/docroot/visit/PatientVisitList.xhtml | 7 ++----- 1.sources/MyHealth/docroot/visit/VisitList.xhtml | 8 ++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/1.sources/MyHealth/docroot/visit/PatientVisitList.xhtml b/1.sources/MyHealth/docroot/visit/PatientVisitList.xhtml index 862a6fa..e1f1b0b 100644 --- a/1.sources/MyHealth/docroot/visit/PatientVisitList.xhtml +++ b/1.sources/MyHealth/docroot/visit/PatientVisitList.xhtml @@ -86,14 +86,11 @@
-
-
- -
+
-
+
diff --git a/1.sources/MyHealth/docroot/visit/VisitList.xhtml b/1.sources/MyHealth/docroot/visit/VisitList.xhtml index 4a8654c..5013168 100644 --- a/1.sources/MyHealth/docroot/visit/VisitList.xhtml +++ b/1.sources/MyHealth/docroot/visit/VisitList.xhtml @@ -71,15 +71,11 @@
-
-
- - -
+
-
+