package managedbean.profile; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.annotation.PostConstruct; import javax.faces.application.FacesMessage; import javax.faces.view.ViewScoped; import javax.inject.Named; import javax.resource.NotSupportedException; import TO.FamilyDoctorTO; import TO.LoggedUserTO; import TO.MedicalSpecialtyTO; import TO.PatientTO; import TO.PrimaryHealthCareCenterTO; import TO.SpecialistDoctorTO; import common.Constants; import common.HashUtils; import common.UserType; import managedbean.common.ManagedBeanBase; import managedbean.common.SessionUtils; import managedbean.common.ValidationUtils; /** * ManagedBEan que gestiona el registro de usuarios: Usuarios de tipo "Paciente" Usuarios de tipo "Médico de Familia" usuarios de tipo "Médico especialista" * * @author Marcos García Núñez (mgarcianun@uoc.edu) * */ @Named("UpdateProfile") @ViewScoped public class UpdateProfileMBean extends ManagedBeanBase implements Serializable { private static final long serialVersionUID = 1L; private int id; private String cipCode; private String nif; private String name; private String surname; private String currentPassword; private String oldPassword; private String password; private String email; private String lastUIQueryPH; private String lastUIQueryMS; private String lastUIQueryFD; private List userTypes; private UserType userType; private PrimaryHealthCareCenterTO primaryHealthCareCenter; private MedicalSpecialtyTO medicalSpecialty; private List medicalSpecialitiesList; private List primaryHealthCareCentersList; private FamilyDoctorTO familyDoctor; private List familyDoctorList; public UpdateProfileMBean() { } /** * Inicializa el Bean: * * Carga la lsita de tipos de usuario (perfiles) Recupera los datos del usuario logeado actualmente, y los asigna a las propiedades del managedBean. * */ @PostConstruct public void init() { this.userTypes = new ArrayList(); this.userTypes.add(UserType.PATIENT); this.userTypes.add(UserType.FAMILY_DOCTOR); this.userTypes.add(UserType.SPECIALIST_DOCTOR); this.lastUIQueryPH = ""; this.lastUIQueryMS = ""; // Recuperamos el usuario logeado actual LoggedUserTO usr = null; usr = SessionUtils.getloggedOnUser(); if (usr == null) this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Sesión no válida", "Su sesión actual no es válida, por favor cierre su sesión y vuelva a logearse en el sistema."); else { this.userType = usr.getUserType(); this.id = Integer.valueOf(usr.getId()); switch (usr.getUserType()) { case PATIENT: this.familyDoctorList = this.getRemoteManagerCommon().listFamilyDoctorsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); this.setPatientData(this.getRemoteManagerCommon().findPatientById(this.id)); break; case SPECIALIST_DOCTOR: this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); this.setSpecialistDoctorData(this.getRemoteManagerCommon().findSpecialistDoctorById(this.id)); break; case FAMILY_DOCTOR: this.primaryHealthCareCentersList = this.getRemoteManagerCommon().listCAPsPaged(0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); this.setFamilyDoctorData(this.getRemoteManagerCommon().findFamilyDoctorById(this.id)); break; case ADMINISTRATOR: this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Usuario sin perfil", "Usted es un usuario de tipo administrador y no puede editar su perfil de usuario."); break; } } } /** * Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un paciente * * @param pat Paciente que está editando su perfil, y cuyos datos deben mostrarse en la vista. */ private void setPatientData(PatientTO pat) { this.id = pat.getId(); this.cipCode = pat.getPersonalIdentificationCode(); this.name = pat.getName(); this.surname = pat.getSurname(); this.nif = pat.getNif(); this.email = pat.getEmail(); this.currentPassword = pat.getPassword(); this.familyDoctor = pat.getFamilyDoctor(); } /** * Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un médico de familia * * @param fd FamilyDoctor que está editando su perfil, y cuyos datos deben mostrarse en la vista. */ private void setFamilyDoctorData(FamilyDoctorTO fd) { this.id = fd.getId(); this.cipCode = fd.getProfessionalNumber(); this.name = fd.getName(); this.surname = fd.getSurname(); this.nif = fd.getNif(); this.email = fd.getEmail(); this.currentPassword = fd.getPassword(); this.primaryHealthCareCenter = fd.getPrimaryHealthCareCenter(); } /** * Establece los valores de las propiedades del managedBean a partir de los datos de un Transfer Object de un médico especialista * * @param sd SpecialistDoctor que está editando su perfil, y cuyos datos deben mostrarse en la vista. */ private void setSpecialistDoctorData(SpecialistDoctorTO sd) { this.id = sd.getId(); this.cipCode = sd.getProfessionalNumber(); this.name = sd.getName(); this.surname = sd.getSurname(); this.nif = sd.getNif(); this.email = sd.getEmail(); this.currentPassword = sd.getPassword(); this.medicalSpecialty = sd.getMedicalSpecialty(); } public List getUserTypes() { return userTypes; } public List getMedicalSpecialtiesList() { return medicalSpecialitiesList; } public List getPhcList() { return primaryHealthCareCentersList; } /** * Método que implementa la búsqueda de un CAP a través del termino tecleado por el usuario en la lista de selección * * @param query Termino tecleado por el usuario * @return Lista de CAPs que coinciden con el termino búscado por el usuario. */ public List completePrimaryHealCareCenter(String query) { if (query != null && query.equals(this.lastUIQueryPH) == false) { this.lastUIQueryPH = query; // Recuperamos las XXX primeras coincidencias this.primaryHealthCareCentersList = this.getRemoteManagerCommon().listCAPsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); } return this.primaryHealthCareCentersList; } /** * Método que implementa la búsqueda de una especialidad a través del termino tecleado por el usuario en la lista de selección * * @param query Termino tecleado por el usuario * @return Lista de especialidades que coinciden con el termino búscado por el usuario. */ public List completeMedicalSpecialty(String query) { if (query != null && query.equals(this.lastUIQueryMS) == false) { this.lastUIQueryMS = query; // Recuperamos las XXX primeras coincidencias this.medicalSpecialitiesList = this.getRemoteManagerCommon().listMedicalSpecialitiesFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); } return this.medicalSpecialitiesList; } /** * Búsca si el NIF ya está en uso para otro usuario. Solo se permite que el mismo NIF se refistro como paciente y como médico (especialista o de familia, pero no como ambos). * * Un Médico puede estar registrado como paciente con el mismo NIF, pero como médico de familia y especialista al mismo tiempo. */ public boolean checkNIFDuplicated(String nifValue, UserType userType, Integer userId) { return ValidationUtils.checkIfNifAlreadyRegistered(this.getRemoteManagerCommon(), userType, nifValue, userId); } public List getFamilyDoctorList() { return familyDoctorList; } /** * Método que implementa la búsqueda de un médico de familia a través del termino tecleado por el usuario en la lista de selección * * @param query Termino tecleado por el usuario * @return Lista de médicos de familia que coinciden con el termino búscado por el usuario. */ public List completeFamilyDoctor(String query) { if (query != null && query.equals(this.lastUIQueryFD) == false) { this.lastUIQueryFD = query; // Recuperamos las 200 primeras coincidencias this.familyDoctorList = this.getRemoteManagerCommon().listFamilyDoctorsFiltered(query, 0, Constants.MAX_ITEMS_AUTOCOMPLETE_SEARCH); } return this.familyDoctorList; } public boolean isUserTypePatient() { return (this.userType == UserType.PATIENT); } public boolean isUserTypeFamilyDoctor() { return (this.userType == UserType.FAMILY_DOCTOR); } public boolean isUserTypeSpecialistDoctor() { return (this.userType == UserType.SPECIALIST_DOCTOR); } public boolean isUserTypeDoctor() { return (isUserTypeFamilyDoctor() || isUserTypeSpecialistDoctor()); } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNif() { return nif; } public void setNif(String nif) { this.nif = nif; } public int getId() { return id; } /** * Método que guarda los datos realizados en la modificación del perfil. Tiene en cuenta el tipo de usuario que está editando su perfil. * * Si el usuario es un médico de familia requiere que se seleccione un CAP para el usuario. Si el usuario es un médico especialista requiere que se seleccione una especialidad * médica para el usuario. Se comprueba que el NIF especificado sea válido y no pertenezca a otro usuario registrado (ver relgas de NIF permitidos para usuarios en el método * handleNIFValueChange) * * Si se especifica una nueva contraseña, entonces se realiz un cambio de contraseña, y se requiere además: Que la nueva contraseña sea diferente a la anterior. * * Después de guardar los datos, se actualizan los datos guardados en la sesión actual para reflejar un posible cambio de nombre y/o apellidos. */ public void saveData() { int error = 0; // Si no hay tipo de usuario, es que algo raro ha pasado (sesión caducada?). salimos. if (this.userType == null) return; try { this.nif = ValidationUtils.normalizeNIF(this.nif); boolean changePassword = (this.oldPassword != null && this.oldPassword.equals("") == false) || (this.password != null && this.password.equals("") == false); if (this.userType == UserType.ADMINISTRATOR) { this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Perfil de usuario incorrecto", "Su perfil es de un usuario de tipo administrador y no puede editar su perfil."); error++; } if (this.isUserTypeFamilyDoctor() && this.primaryHealthCareCenter == null) { this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Centro de atención primaria no seleccionado", "Por favor, especifique un centro de atención primaria."); error++; } if (this.isUserTypeSpecialistDoctor() && this.medicalSpecialty == null) { this.addFacesMessage(FacesMessage.SEVERITY_WARN, "Especialidad médica no seleccionada", "Por favor, especifique una especialidad médica."); error++; } if (ValidationUtils.isValid(nif) == false) { this.addFacesMessage(FacesMessage.SEVERITY_WARN, "El NIF indicado no es válido", "Por favor, especifique un NIF válido."); error++; } if (ValidationUtils.checkIfNifAlreadyRegistered(this.getRemoteManagerCommon(), this.userType, this.nif, this.id) == true) { this.addFacesMessage("frmUpdateProfile:nif", FacesMessage.SEVERITY_WARN, "NIF duplicado", "El nif indicado pertenece a otro usuario previamente registrado"); error++; } if (changePassword == true) { // el usuario queire cambiar el password Comprobamos que el password // especificado coincide con el guardado if (this.password == null || this.password.length() < 4) { this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Nueva contraseña incorrectra", "Su nueva contraseña debe tener al menos 4 caracteres."); error++; } else if (HashUtils.hashMD5(this.oldPassword).equals(this.currentPassword) == false) { this.addFacesMessage(FacesMessage.SEVERITY_ERROR, "Contraseña actual incorrecta", "Su actual contraseña es incorrecta. Por favor, especifique su contraseña actual."); error++; } } if (error == 0) { LoggedUserTO usr = null; switch (this.userType) { case PATIENT: PatientTO pat = this.getRemoteManagerProfile().updatePatientData(id, nif, name, surname, password, email); this.setPatientData(pat); usr = new LoggedUserTO(pat.getId().toString(), pat.getName(), pat.getPassword(), this.userType, pat.getDisplayName()); break; case FAMILY_DOCTOR: FamilyDoctorTO fd = this.getRemoteManagerProfile().updateFamilyDoctorData(id, nif, name, surname, password, email, this.primaryHealthCareCenter); this.setFamilyDoctorData(fd); usr = new LoggedUserTO(fd.getId().toString(), fd.getName(), fd.getPassword(), this.userType, fd.getDisplayName()); break; case SPECIALIST_DOCTOR: SpecialistDoctorTO sd = this.getRemoteManagerProfile().updateSpecialistDoctorData(id, nif, name, surname, password, email, this.medicalSpecialty); this.setSpecialistDoctorData(sd); usr = new LoggedUserTO(sd.getId().toString(), sd.getName(), sd.getPassword(), this.userType, sd.getDisplayName()); break; case ADMINISTRATOR: break; } if (changePassword == true) { this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Contraseña actualizada", "Su contraseña ha sido actualizada correctamente."); this.password = ""; this.oldPassword = ""; } // Actualizamos la sessión del usuario actual por si ha cambiado el nombre de usuario. SessionUtils.createOrUpdateSession(usr); this.addFacesMessage(FacesMessage.SEVERITY_INFO, "Los datos se han guardado", "Los datos de su perfil se han guardado correctamente."); } } catch (Exception ex) { this.manageException(ex); } } public UserType getUserType() { return userType; } public void setUserType(UserType value) { this.userType = value; } public MedicalSpecialtyTO getMedicalSpecialty() { return medicalSpecialty; } public void setMedicalSpecialty(MedicalSpecialtyTO medicalSpecialty) { this.medicalSpecialty = medicalSpecialty; } public PrimaryHealthCareCenterTO getPrimaryHealthCareCenter() { return primaryHealthCareCenter; } public void setPrimaryHealthCareCenter(PrimaryHealthCareCenterTO primaryHealthCareCenter) { this.primaryHealthCareCenter = primaryHealthCareCenter; } public String getOldPassword() { return oldPassword; } public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; } public FamilyDoctorTO getFamilyDoctor() { return familyDoctor; } public void setFamilyDoctor(FamilyDoctorTO familyDoctor) { this.familyDoctor = familyDoctor; } public String getCipCode() { return cipCode; } }