DavixDavix ERPX
Modulos

Horarios

Asignacion y gestion de horarios de atencion para medicos y equipos medicos con calendario interactivo FullCalendar, especialidades, lugares de atencion, modalidades y tipos de atencion.

Que es Horarios

El modulo Colaboradores Horarios permite asignar horarios de atencion a medicos individuales o equipos medicos. Cada horario define las especialidades, lugares de atencion, modalidades y tipos de atencion disponibles. Los bloques horarios individuales (detalles) se programan dia a dia desde un calendario interactivo FullCalendar.

Los horarios configurados aqui se utilizan en el modulo de Sistema de Información Clínica (HIS) para gestionar citas y atenciones medicas. Los medicos provienen del modulo de Salud y los equipos medicos de su configuracion correspondiente. Verifica que tienes el perfil adecuado.


Acceso

Breadcrumb: Inicio > RRHH > Colaboradores horarios

  • Inicio y RRHH son enlaces que redirigen a / y /rrhh respectivamente.
  • Colaboradores horarios es la pagina actual (sin enlace).

Titulo de pagina: "Lista de colaboradores horarios" Subtitulo: "Muestra el listado y las herramientas para gestionar los colaboradores horarios"


Barra de herramientas

BotonIconoEstiloDescripcion
Actualizarpi pi-refreshOutlined, secundarioRecarga la tabla ejecutando nuevamente la consulta al servidor.
Nuevo horariopi pi-plusRaised, primarioAbre el formulario de creacion de horario a pantalla completa.

Tabla de horarios

La tabla utiliza un componente p-table con las siguientes caracteristicas:

  • Lazy loading: los datos se cargan bajo demanda al cambiar de pagina.
  • Seleccion multiple: se pueden seleccionar varias filas (selectionMode="multiple").
  • Menu contextual: clic derecho sobre cualquier fila abre el menu contextual.
  • Columnas redimensionables: las columnas se pueden ajustar arrastrando los bordes (columnResizeMode="expand").
  • Scroll: la altura de la tabla se calcula dinamicamente segun la altura de la ventana, restando la cabecera, el pie de paginacion y un margen de 150px.

Columnas

#ColumnaAnchoDescripcion
1MEDICO / EQUIPO MEDICOAutomaticoSi el registro tiene un colaborador asignado, muestra: numero_documento - apellido_paterno apellido_materno nombres. Si tiene un equipo medico, muestra el campo nombre del equipo.
2ESPECIALIDADESAutomaticoLista de nombres de especialidades del horario, separadas por coma. Se obtiene de especialidades[].especialidad.nombres.
3Acciones80px fijoIcono de tres puntos horizontales (pi pi-ellipsis-h) que abre el menu contextual mediante clic.

Mensaje vacio

Cuando no hay registros la tabla muestra: "No se encontraron datos" con icono pi pi-exclamation-triangle.

Indicador de carga

Encima de la tabla se muestra el texto: "Mostrando pagina {N} con {X} registros de {Z} entradas" donde N es la pagina actual + 1, X es la cantidad de registros de la pagina y Z el total.


Se activa con clic derecho sobre una fila o con clic en el icono de tres puntos de la columna Acciones.

OpcionIconoDescripcion
Ver horariospi pi-eyeAbre el calendario interactivo FullCalendar con los bloques horarios del medico/equipo.
(separador)
Editarpi pi-bookAbre el formulario de edicion del horario a pantalla completa.
Eliminarpi pi-trashAbre el dialogo de confirmacion de eliminacion (ancho 50vw, modal).

Paginacion

La paginacion se ubica debajo de la tabla. Cada pagina muestra 50 registros (parametro size: 50).

ControlIconoDescripcion
Primerapi pi-angle-double-leftIr a la primera pagina. No hace nada si from ya es 0.
Anteriorpi pi-angle-leftIr a la pagina anterior. No hace nada si ya esta en la pagina 0.
DropdownSelector de pagina con formato "X de Y". Tiene filtro de busqueda habilitado. emptyMessage: "Sin paginas", emptyFilterMessage: "Sin resultados".
Siguientepi pi-angle-rightIr a la pagina siguiente. No hace nada si ya esta en la ultima.
Ultimapi pi-angle-double-rightIr a la ultima pagina. No hace nada si ya esta ahi.

Calculo de paginas: el total de registros se divide entre el tamano de pagina (50). Si hay un residuo, se agrega una pagina adicional.

Parametros de consulta: la paginacion usa los parametros from (offset) y size (50). El offset se calcula como current * size + 1 (excepto la primera pagina que es from=0).


Crear horario

Al presionar "Nuevo horario" se abre un DynamicDialog a pantalla completa (100% ancho, 100% alto, no modal).

Titulo del dialogo: "Nuevo horario"

Estado de carga

Mientras se obtienen los datos iniciales se muestra:

  • Texto: "Cargando sus datos"
  • Icono de spinner animado
  • Barra de progreso indeterminada (p-progressBar, 6px de alto)

Datos iniciales

Al abrir el formulario se ejecutan dos consultas en paralelo (forkJoin):

  1. Medicos: GET /v2.0.4/erpx/salud/medicos/?search=**&from=0&size=10 — carga los primeros 10 medicos.
  2. Equipos medicos: GET /v2.0.1/erpx/salud/equipos-medicos/?search=**&from=0&size=10 — carga los primeros 10 equipos.

Cada medico se formatea como: numero_documento - apellido_paterno apellido_materno nombres. Cada equipo medico se formatea con su campo nombre.

Seccion del formulario

Titulo de seccion: "Detalles de estudios" (sic — asi aparece en el codigo fuente) Indicacion: "Se tiene que rellenar los campos que contengan (*) obligatoriamente que se requiere para el registro."

Campos del formulario

CampoTipoObligatorioTooltipValores por defectoMensaje de error
TipoRadioButton (p-radioButton)Si"Seleccione el colaborador"0 (Medico)
MedicoDropdown con busqueda remota (p-dropdown)Si (si tipo = 0)"Seleccione el colaborador"null* Ingrese colaborador valido
Equipo medicoDropdown con busqueda remota (p-dropdown)Si (si tipo = 1)"Seleccione el equipo medico"null* Ingrese un equipo medico valido
EspecialidadesMultiSelect (p-multiSelect)Si"Seleccione la especialidades" (sic)[]* Ingrese especialidades valido
Lugares de atencionMultiSelect (p-multiSelect)Si"Seleccione los lugares"[]* Ingrese lugares valido
ModalidadesMultiSelect (p-multiSelect)Si"Seleccione las modalidades"[]* Ingrese modalidades valida
Tipos de atencionMultiSelect (p-multiSelect)Si"Seleccione los tipos de atencion"[]* Ingrese tipos de atencion valida

Todos los dropdowns y multiselects muestran:

  • Placeholder: "SELECCIONE"
  • emptyMessage: "No se encontraron registros."
  • emptyFilterMessage: "No se han encontrado resultados"

Opciones del campo Tipo

OpcionValorInput IDDescripcion
Medico0tipo1Muestra el campo Medico y oculta Equipo medico.
Equipo medico1tipo2Muestra el campo Equipo medico y oculta Medico.

Opciones fijas de Modalidades

OpcionValor interno
EN CONSULTORIO1
VIRTUAL2

Opciones fijas de Tipos de atencion

OpcionValor interno
CONSULTACONSULTA
RECONSULTARECONSULTA
PROCEDIMIENTO MEDICOPROCEDIMIENTO MEDICO

Comportamiento dinamico

Al cambiar el Tipo

Al cambiar entre Medico y Equipo medico se reinician los campos: Medico/Equipo medico, Especialidades y Lugares de atencion. Las validaciones required se actualizan: solo el campo visible es obligatorio.

Busqueda remota en el dropdown de Medico

Al escribir en el filtro del dropdown de Medico se ejecuta:

GET /v2.0.4/erpx/salud/medicos/?search=*{TEXTO_EN_MAYUSCULAS}*&from=0&size=10

El texto ingresado se convierte a mayusculas y se envuelve en comodines *...*. Se retornan los primeros 10 resultados.

Busqueda remota en el dropdown de Equipo medico

Al escribir en el filtro del dropdown de Equipo medico se ejecuta:

GET /v2.0.1/erpx/salud/equipos-medicos/?search=*{TEXTO_EN_MAYUSCULAS}*&from=0&size=10

Misma logica: texto en mayusculas con comodines, 10 resultados maximo.

Al seleccionar un Medico

  • Las Especialidades disponibles se cargan desde colaborador.especialidades.
  • Los Lugares de atencion disponibles se cargan desde colaborador.lugares_atenciones.
  • Si el medico tiene una sola especialidad, se preselecciona automaticamente.
  • Si tiene un solo lugar de atencion, se preselecciona automaticamente.

Al seleccionar un Equipo medico

  • Las Especialidades se cargan desde equipo_medico.especialidad (se envuelve en array).
  • Los Lugares de atencion se cargan desde equipo_medico.lugar_atencion (se envuelve en array).
  • La misma logica de autoseleccion si hay un solo elemento.

Botones del formulario

Los botones estan fijos en la parte inferior de la pantalla (position: fixed; bottom: 0).

BotonIconoEstiloDescripcion
Cancelarpi pi-timesTexto, primarioCierra el dialogo sin guardar.
Guardarpi pi-checkRaised, primarioValida y guarda. Muestra spinner de carga mientras procesa ([loading]).

Payload al guardar

El formulario construye el siguiente payload:

\{
  "id": null,
  "colaborador_id": "<id del medico o null>",
  "equipo_medico_id": "<id del equipo o null>",
  "especialidades": [\{ "especialidad_id": "<id>" \}],
  "modalidades": [\{ "modalidad": "<valor numerico>" \}],
  "atenciones_tipos": [\{ "atencion_tipo": "<valor string>" \}],
  "lugares": [\{ "lugar_id": "<id>" \}]
\}
  • Creacion: POST /v2.0.2/erpx/rrhh/colaboradores-horarios/
  • Actualizacion: PUT /v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}

Despues de guardar, se hace GET /v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\} para obtener el registro completo actualizado y retornarlo a la lista.

Resultado al guardar

ResultadoSeveritySummaryMensajeDuracion
Creacion exitosasuccess"Alerta""Creado con exito"5 segundos
Actualizacion exitosasuccess"Alerta""Actualizado con exito"5 segundos
Error de validacion (formulario invalido)error"Alerta""Revise bien, hay formularios por validar."5 segundos

Editar horario

Al seleccionar Editar en el menu contextual se abre el mismo dialogo a pantalla completa.

Titulo del dialogo: "Actualizar horario {numero_documento - apellido_paterno apellido_materno nombres}" (usa getFormatNombres del campo medico del nodo).

Flujo de carga de datos en modo edicion

Se ejecutan las mismas dos consultas iniciales (medicos y equipos medicos).

Se consulta el horario completo: GET /v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}.

Si el horario tiene colaborador_id, el tipo se fija en Medico (0) y se carga el medico con GET /v2.0.4/erpx/salud/medicos/\{colaborador_id\}. Si tiene equipo_medico_id, el tipo se fija en Equipo medico (1) y se carga con GET /v2.0.1/erpx/salud/equipos-medicos/\{equipo_medico_id\}.

Si el medico/equipo ya esta en la lista de los primeros 10, se selecciona directamente. Si no esta, se agrega a la lista y se selecciona.

Las especialidades, lugares, modalidades y tipos de atencion se preseleccionan buscando coincidencias entre los datos del horario y las opciones disponibles.


Ver horarios (Calendario)

Al seleccionar "Ver horarios" se abre un DynamicDialog a pantalla completa (100% ancho, 100% alto, no modal).

Titulo del dialogo: HORARIOS > \{nombre del medico/equipo\}

El nombre se genera con la misma funcion getMedicoOrEquipoMedico: si tiene colaborador muestra numero_documento - apellido_paterno apellido_materno nombres, si tiene equipo muestra el nombre del equipo.

Estado de carga

Mientras carga los datos muestra:

  • Texto: "Cargando sus datos"
  • Spinner animado
  • Barra de progreso indeterminada (6px)

Datos iniciales del calendario

Se ejecutan tres consultas en paralelo (forkJoin):

  1. Horario padre: GET /v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\} — recarga el horario completo.
  2. Detalles (bloques): GET /v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/?search=** AND colaborador_horario_id:\{id\}&from=0&size=100000000 — obtiene todos los bloques horarios del horario.
  3. Medico o equipo: GET /v2.0.4/erpx/salud/medicos/\{colaborador_id\} o GET /v2.0.1/erpx/salud/equipos-medicos/\{equipo_medico_id\} segun corresponda.

Los bloques se transforman en eventos de FullCalendar con:

  • title: DD/MM/YYYY (HH:mm-HH:mm) (ejemplo: "15/03/2026 (08:00-14:00)")
  • start: YYYY-MM-DD HH:mm:ss
  • end: YYYY-MM-DD HH:mm:ss

Configuracion del calendario FullCalendar

PropiedadValor
PluginsdayGridPlugin, timeGridPlugin, interactionPlugin
Vista inicialdayGridMonth (mes)
IdiomaEspanol (esLocale)
Editablefalse (los eventos no se pueden arrastrar)
dateClickCrea un nuevo bloque horario
eventClickEdita un bloque horario existente

Barra de navegacion del calendario

PosicionControles
IzquierdaAnterior, Siguiente, Hoy
CentroTitulo (mes/semana/dia actual)
DerechaMes (dayGridMonth), Semana (timeGridWeek), Dia (timeGridDay)

Listas de opciones del detalle

Las opciones de Especialidades y Lugares se cargan desde el medico/equipo seleccionado. Las opciones fijas son:

Modalidades:

OpcionValor
EN CONSULTORIO1
VIRTUAL2

Tipos de atencion:

OpcionValor
CONSULTACONSULTA
RECONSULTARECONSULTA
PROCEDIMIENTO MEDICOPROCEDIMIENTO MEDICO

Crear un bloque horario

Haz clic en cualquier dia del calendario. Se abre un dialogo modal titulado "Horario" (ancho 50rem).

Los campos se precargan automaticamente:

  • Fecha: el dia seleccionado.
  • Hora inicio: 00:00 del dia seleccionado.
  • Hora fin: 23:59:59 del dia seleccionado.
  • Especialidades: se preseleccionan todas las del horario padre.
  • Lugares de atencion: se preseleccionan todos los del horario padre.
  • Modalidades: se preseleccionan todas las del horario padre.
  • Tipos de atencion: se preseleccionan todos los del horario padre.

Ajusta la hora inicio, hora fin y demas campos segun necesites.

Presiona Guardar para crear el bloque.

Campos del dialogo de bloque horario

CampoTipoObligatorioTooltipMensaje de error
FechaCalendario p-calendar (formato dd/mm/yy, con icono)Si* Ingrese fecha valido
Hora inicioCalendario p-calendar (solo hora, icono pi pi-clock)Si* Ingrese hora inicio valido
Hora finCalendario p-calendar (solo hora, icono pi pi-clock)Si* Ingrese hora fin valido
EspecialidadesMultiSelect (optionLabel="nombres")Si"Seleccione la especialidades" (sic)* Ingrese especialidades valido
Lugares de atencionMultiSelect (optionLabel="nombre")Si"Seleccione los lugares"* Ingrese lugares valido
ModalidadesMultiSelect (optionLabel="label")Si"Seleccione las modalidades"* Ingrese modalidades valida
Tipos de atencionMultiSelect (optionLabel="label")Si"Seleccione los tipos de atencion"* Ingrese tipos de atencion valida

Todos los multiselects muestran: placeholder "SELECCIONE", emptyMessage "No se encontraron registros.", emptyFilterMessage "No se han encontrado resultados".

Botones del dialogo de bloque

Los botones estan fijos en la parte inferior (position: fixed; bottom: 0).

BotonIconoEstiloCondicionDescripcion
Cancelarpi pi-timesTexto, primarioSiempre visibleCierra el dialogo sin guardar.
Eliminarpi pi-trashDanger (rojo)Solo si es edicion (id no nulo)Elimina el bloque con confirmacion.
Guardarpi pi-checkRaised, primarioSiempre visibleValida y guarda. Muestra spinner.

Payload del bloque horario

Al guardar se formatea:

  • fecha: YYYY-MM-DD
  • hora_inicio: HH:mm:00 (segundos siempre 00)
  • hora_fin: HH:mm:59 (segundos siempre 59)
\{
  "id": null,
  "colaborador_horario_id": "<id del horario padre>",
  "colaborador_id": "<id del medico o null>",
  "equipo_medico_id": "<id del equipo o null>",
  "fecha": "2026-03-15",
  "hora_inicio": "08:00:00",
  "hora_fin": "14:00:59",
  "especialidades": [\{ "id": null, "especialidad_id": "<id>" \}],
  "lugares": [\{ "id": null, "lugar_id": "<id>" \}],
  "modalidades": [\{ "id": null, "modalidad": 1 \}],
  "atenciones_tipos": [\{ "id": null, "atencion_tipo": "CONSULTA" \}]
\}
  • Creacion: POST /v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/
  • Actualizacion: PUT /v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/\{id\}

Resultado al guardar bloque

ResultadoSeveritySummaryMensajeDuracion
Creacion exitosasuccess"Alerta""Creado con exito"5 segundos
Actualizacion exitosasuccess"Alerta""Actualizado con exito"5 segundos
Error de validacionerror"Alerta""Revise bien, hay formularios por validar."5 segundos

Editar un bloque horario

Haz clic en un evento existente del calendario.

Se abre el dialogo "Horario" con todos los campos precargados: fecha, hora inicio, hora fin, especialidades, lugares, modalidades y tipos de atencion del bloque.

Modifica los campos necesarios y presiona Guardar. El evento se actualiza visualmente en el calendario.

Eliminar un bloque horario

Al editar un bloque existente (id no nulo), aparece el boton "Eliminar" (rojo).

Presiona el boton Eliminar.

Se muestra un p-confirmPopup con el mensaje: "Desea eliminar el horario?" e icono pi pi-exclamation-triangle.

Aceptar: ejecuta DELETE /v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/\{id\}. El evento se elimina del calendario y se muestra: "Eliminado con exito" (verde, 5 segundos).

Rechazar: cierra el popup sin eliminar.


Eliminar horario

Al seleccionar Eliminar en el menu contextual de la tabla principal se abre un DynamicDialog modal (ancho 50vw).

ElementoDetalle
Titulo del dialogo"Confirmacion"
Iconopi pi-exclamation-triangle (tamano 2rem)
Mensaje"Estas seguro de proceder con la baja?"

Botones

BotonIconoEstiloDescripcion
Nopi pi-timesTextoCierra el dialogo sin eliminar.
Sipi pi-checkPrimarioEjecuta la eliminacion. El icono cambia a spinner (pi-spin pi-spinner) mientras se procesa.

Endpoint

DELETE /v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}

Resultado

ResultadoSeveritySummaryMensajeDuracion
Eliminacion exitosasuccess"Alerta""Eliminado."5 segundos
Errorerror"Error {status}"Segun el codigo HTTP (ver seccion Errores)5 segundos

Al eliminar un horario se eliminan todos los bloques horarios (detalles) asociados. Esta accion es permanente.


Endpoints del modulo

Colaboradores Horarios

MetodoEndpointDescripcion
GET/v2.0.2/erpx/rrhh/colaboradores-horarios/?search=\{filtro\}&from=\{offset\}&size=\{tamano\}Listar horarios con paginacion
GET/v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}Obtener un horario por ID
POST/v2.0.2/erpx/rrhh/colaboradores-horarios/Crear horario
PUT/v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}Actualizar horario
DELETE/v2.0.2/erpx/rrhh/colaboradores-horarios/\{id\}Eliminar horario

Colaboradores Horarios Detalles (bloques)

MetodoEndpointDescripcion
GET/v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/?search=\{filtro\}&from=\{offset\}&size=\{tamano\}Listar detalles
GET/v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/\{id\}Obtener detalle por ID
POST/v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/Crear detalle
PUT/v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/\{id\}Actualizar detalle
DELETE/v2.0.3/erpx/rrhh/colaboradores-horarios-detalles/\{id\}Eliminar detalle

Otros endpoints consumidos

MetodoEndpointDescripcion
GET/v2.0.4/erpx/salud/medicos/?search=\{filtro\}&from=0&size=10Buscar medicos
GET/v2.0.4/erpx/salud/medicos/\{id\}Obtener medico por ID
GET/v2.0.1/erpx/salud/equipos-medicos/?search=\{filtro\}&from=0&size=10Buscar equipos medicos
GET/v2.0.1/erpx/salud/equipos-medicos/\{id\}Obtener equipo medico por ID

Formato de busqueda: search=** para traer todos, search=*TEXTO* para filtrar (texto en mayusculas envuelto en comodines).

Headers requeridos: Authorization: Bearer \{token\}, enterprise-id: \{id\}, accept: application/json.


Manejo de errores

El modulo tiene dos funciones de manejo de errores:

errorsRequest (general)

Codigo HTTPMensaje mostrado
400"Error de estructura de envio de datos. ERROR 400"
404"No se encontro el servidor de respuestas, consulte con el Administrador. ERROR 404"
500"Error interno del servidor. ERROR 500"
401, 402, 403Concatena los mensajes del array error.error.errors[].messague (sic) separados por coma
Otro"Error 404 consulte con su admin."

Se usa en: listado de horarios, busqueda remota de medicos, busqueda remota de equipos medicos, formulario de creacion/edicion.

errorsRequest del componente Destroy

Codigo HTTPMensaje mostrado
400, 402Muestra directamente error.error.errors[0] (primer elemento del array como string)
404"No se encontro el servidor de respuestas, consulte con el Administrador. ERROR 404"
500"Error interno del servidor. ERROR 500"
Otro"Error 404 consulte con su admin."

Todas las notificaciones de error usan: severity: 'error', summary: 'Error \{status\}', duracion 5 segundos.


Problemas comunes

ProblemaCausaSolucion
No aparecen especialidades al seleccionar un medicoEl medico no tiene especialidades registradas en el modulo Salud.Registra las especialidades del medico desde la configuracion de Sistema de Información Clínica (HIS).
No aparecen lugares de atencionEl medico/equipo no tiene lugares asignados.Asigna lugares de atencion desde la configuracion correspondiente.
"Revise bien, hay formularios por validar"Hay campos obligatorios sin completar.Completa todos los campos marcados con (*).
El calendario no muestra eventosNo se han creado bloques horarios (detalles) para ese medico/equipo.Haz clic en un dia del calendario para crear un nuevo bloque.
No encuentro el medico en el dropdownEl medico no esta entre los primeros 10 resultados.Escribe parte del nombre o numero de documento en el filtro para ejecutar la busqueda remota.
Al cambiar tipo se borran las especialidadesComportamiento esperado: al cambiar entre Medico y Equipo medico se reinician los campos dependientes.Selecciona nuevamente el medico/equipo y sus especialidades se cargaran.
La hora fin aparece con :59 segundosEl sistema guarda la hora fin con 59 segundos (formato HH:mm:59).Es el comportamiento normal, no es un error.

Paginas relacionadas