com.cdsoftware.appointment

Documentación técnica del plugin iDempiere 12 para gestión reutilizable de citas, servicios, empleados, horarios, disponibilidad, generación de slots y validación centralizada desde UI o API.

Visión General

Resumen funcional y arquitectura general del plugin de citas.

Visión General

Resumen del Plugin

El plugin com.cdsoftware.appointment agrega a iDempiere 12 un módulo reutilizable para gestionar citas, servicios, empleados, horarios, días no disponibles y disponibilidad de agenda.

Idea clave: la disponibilidad no depende solo de la interfaz. La validación queda centralizada en backend para proteger tanto las citas creadas desde ventanas iDempiere como las creadas desde REST/API.

Objetivo

El objetivo es permitir que una organización configure servicios agendables, defina qué empleados pueden atender cada servicio, establezca horarios de atención y bloquee días o rangos no disponibles. Con esa información, el sistema genera slots disponibles y valida cada cita antes de guardarla.

Alcance funcional

ÁreaQué cubre
ConfiguraciónParámetros generales por organización, límites de anticipación, reglas de aprobación e intervalos de slots.
ServiciosServicios agendables con precio, duración, intervalo, capacidad y requerimiento de aprobación.
EmpleadosPersonas o usuarios disponibles para atender citas, vinculados a terceros y opcionalmente a usuarios iDempiere.
DisponibilidadHorarios semanales, días libres de empleado, días libres de organización y validación de conflictos.
CitasRegistro principal de la cita con cliente, empleado, servicio, fecha, hora, duración, precio, estado y slot seleccionado.

Principios de diseño

Visión General

Arquitectura y Componentes

La arquitectura del plugin separa la definición de modelos, la disponibilidad, la experiencia de ventana iDempiere y la validación obligatoria antes de guardar citas.

Componentes principales

ComponenteResponsabilidad
AppointmentAvailabilityEngineCentraliza cálculo de disponibilidad, validación de horarios, días libres, conflictos y generación de slots.
AppointmentModelValidatorValida citas antes de crear o modificar registros, incluyendo consistencia del slot y conflictos de agenda.
CalloutAppointmentApoya la captura en ventana iDempiere copiando precio, duración, empleado y horas desde servicio o slot.
GenerateAppointmentSlotsGenera registros CDS_AppointmentSlot para un empleado, servicio y fecha específicos.
ReopenAppointmentPermite reabrir una cita procesada de forma controlada.

Flujo general

  1. El usuario configura servicios, empleados, capacidades, horarios y días no disponibles.
  2. Desde una cita se selecciona empleado, servicio y fecha.
  3. El proceso de generación crea slots disponibles para esa combinación.
  4. El usuario selecciona un slot y el callout copia datos a la cita.
  5. Al guardar, el evento valida disponibilidad, consistencia y conflictos.
  6. Los clientes REST/API pueden crear la cita directamente y reciben la misma validación por evento.

Nota: los callouts mejoran la experiencia de captura, pero no son la capa de seguridad. La regla final vive en AppointmentModelValidator.

Visión General

Flujo de Configuración y Cita

Esta página describe el flujo objetivo para preparar una agenda y poder crear citas válidas. El flujo parte de una configuración general, continúa con servicios y empleados, y termina con la creación de una cita validada por backend.

Importante: parte de este flujo representa el comportamiento objetivo. Algunas reglas todavía deben implementarse en el modelo y en AppointmentModelValidator para que sean obligatorias tanto desde la UI como desde REST/API.

Flujo objetivo

yoFttEn6HSRcxnol-drawing-1-1779470586.png

Secuencia funcional

  1. Crear una configuración de agenda por organización o por alcance operativo.
  2. Definir reglas generales como anticipación mínima, anticipación máxima, regla de asignación y política de aprobación.
  3. Definir el horario macro de la agenda. Por ejemplo: lunes a viernes de 8:00 a 17:00.
  4. Relacionar cada servicio con una sola configuración de agenda.
  5. Configurar cada servicio con duración, precio, intervalo de slot y si requiere aprobación.
  6. Configurar empleados y definir qué servicios puede atender cada uno.
  7. Definir horario laboral y días libres del empleado.
  8. Crear la cita seleccionando empleado, servicio, fecha y slot.
  9. Validar primero la configuración de agenda y luego las reglas del empleado.
  10. Guardar la cita como pendiente o aprobada según las reglas de aprobación.

Jerarquía de disponibilidad esperada

Nivel Regla Prioridad
Configuración de agenda Define el marco general de operación: anticipación, días permitidos, horarios macro y aprobación. Debe estar por encima del empleado. Si la agenda general está cerrada, ningún empleado puede abrir disponibilidad.
Servicio Define duración, precio, intervalo y si requiere aprobación. Debe resolver qué configuración aplica.
Empleado Define servicios que puede atender, horario propio y bloqueos personales. Solo puede reducir o especializar la disponibilidad de la configuración, no ampliarla.
Cita Consume empleado, servicio, configuración, slot y reglas de conflicto. Debe ser validada por evento antes de guardarse.

Reglas pendientes para completar el flujo

Modelo de Datos

Tablas, modelos generados y relaciones principales del módulo.

Modelo de Datos

Tablas y Modelo de Datos

El 2Pack del plugin define las tablas del módulo y genera modelos Java I_CDS_* y X_CDS_*. El código usa esos modelos como fuente de nombres de tabla, columnas y valores de referencia.

Tablas principales

TablaUso
CDS_AppointmentConfigConfiguración organizacional de agenda, reglas de asignación, aprobación, límites e intervalos.
CDS_AppointmentServiceServicios agendables con precio, duración, intervalo de slot, aprobación requerida y capacidad.
CDS_AppointmentEmployeeEmpleado disponible para citas, vinculado a C_BPartner y opcionalmente a AD_User.
CDS_EmployeeServiceRelación empleado-servicio con posibles overrides de precio y duración.
CDS_EmployeeScheduleLineBloques semanales de disponibilidad del empleado por día y rango horario.
CDS_EmployeeDayOffBloqueos de empleado por día completo o rango horario, incluyendo recurrencia anual.
CDS_OrgDayOffBloqueos de organización por día completo o rango horario. Incluye CDS_AppointmentConfig_ID, aunque el motor actual todavía no filtra por configuración.
CDS_AppointmentSlotSlots generados para selección desde la ventana iDempiere y consulta desde API.
CDS_AppointmentRegistro principal de cita con cliente, empleado, servicio, fecha, hora, precio, duración, estado y slot.

Relaciones clave actuales

Tabla CDS_AppointmentSlot

CDS_AppointmentSlot almacena horarios generados por usuario para que la UI o un cliente API pueda listar opciones disponibles después de ejecutar GenerateAppointmentSlots.

ColumnaUsoFiltro API recomendado
CDS_AppointmentSlot_IDIdentificador del slot seleccionado.Usar al copiar el slot hacia CDS_Appointment.CDS_AppointmentSlot_ID.
AD_Org_IDOrganización del slot.Filtrar por organización activa del usuario.
AD_User_IDUsuario que generó el slot.Filtrar por usuario actual para no mezclar slots temporales de otros usuarios.
CDS_Appointment_IDCita desde la cual se generó el slot, si aplica.Filtrar cuando los slots se generaron desde una cita específica.
CDS_AppointmentEmployee_IDEmpleado disponible para atender el slot.Filtrar por empleado seleccionado.
CDS_AppointmentService_IDServicio del slot.Filtrar por servicio seleccionado.
SlotDateFecha del slot normalizada al inicio del día.Filtrar por fecha de la cita.
StartDateTimeInicio exacto del horario disponible.Ordenar ascendente o filtrar por rango horario.
EndDateTimeFin exacto del horario disponible.Usar junto con StartDateTime para mostrar rango.
DisplayNameEtiqueta legible del horario.Mostrar como texto de selección.
IsAvailableIndica si el slot sigue disponible.Filtrar IsAvailable='Y'.
IsActiveControl estándar de registro activo.Filtrar IsActive='Y'.
AvailableEmployeesCantidad de empleados disponibles para el rango. En el flujo actual por empleado suele quedar en 1.Usar solo como referencia informativa.
PricePrecio efectivo del slot.Copiar a la cita si se selecciona el slot.
DurationMinutesDuración efectiva del slot.Copiar a la cita si se selecciona el slot.
AssignedByRuleIndica si el empleado fue asignado por regla automática.Actualmente informativo en el flujo por empleado.
AssignmentRuleUsedRegla de asignación usada al generar el slot.Usar para auditoría o depuración.

Consulta típica API: después de generar slots, listar CDS_AppointmentSlot filtrando por AD_User_ID, CDS_AppointmentEmployee_ID, CDS_AppointmentService_ID, SlotDate, IsActive='Y' e IsAvailable='Y', ordenando por StartDateTime.

Relación configuración-servicio pendiente

El flujo objetivo requiere que cada servicio resuelva una configuración de agenda. Esto permite saber qué reglas de anticipación, horarios macro, días cerrados y aprobación aplican cuando se crea una cita.

NecesidadOpción recomendadaValidación requerida
Servicio pertenece a una configuraciónAgregar CDS_AppointmentConfig_ID en CDS_AppointmentService.El servicio debe tener una configuración activa cuando se use para generar slots o crear citas.
Un servicio no puede tener reglas ambiguasSi se usa tabla intermedia, imponer unicidad por servicio activo.Bloquear más de una configuración activa por servicio.
Días libres por configuraciónUsar el campo existente CDS_AppointmentConfig_ID de CDS_OrgDayOff.El motor debe filtrar bloqueos por organización y por configuración del servicio.

Horario macro de configuración pendiente

Actualmente solo existe horario de empleado. Para cumplir el flujo objetivo se recomienda agregar una tabla de horario macro, por ejemplo CDS_AppointmentConfigScheduleLine, con una estructura similar a CDS_EmployeeScheduleLine.

Campo sugeridoUso
CDS_AppointmentConfig_IDConfiguración de agenda a la que pertenece el horario macro.
WeekDayDía de la semana permitido.
StartTime / EndTimeRango horario general de atención.
ValidFrom / ValidToVigencia opcional del horario.

Importante: si el diccionario cambia, se deben regenerar los modelos antes de ajustar el código Java.

Lógica Backend

Motor de disponibilidad, callouts, procesos y validaciones por evento.

Lógica Backend

Motor de Disponibilidad

AppointmentAvailabilityEngine concentra la lógica que decide si una cita o un slot es válido para un empleado, servicio y fecha determinados.

Responsabilidades actuales

Regla de conflicto

Una cita se considera en conflicto cuando otra cita activa del mismo empleado se cruza con el rango nuevo y tiene estado pendiente o aprobado.

existing.StartDateTime < newEnd
AND existing.EndDateTime > newStart
AND existing.Status IN ('PE', 'AP')
AND existing.IsActive = 'Y'

Generación de slots

La generación actual es específica por empleado. El proceso no genera para todos los empleados ni autoasigna el recurso; parte de una selección explícita de empleado, servicio y fecha.

Nota: esta decisión hace que el flujo de UI sea más claro: primero se elige quién atiende, luego qué servicio presta, después se generan horarios disponibles.

Reglas actuales vs reglas esperadas

ReglaEstado actualComportamiento esperado
Empleado presta servicioImplementado con CDS_EmployeeService.Se mantiene como regla obligatoria.
Día libre de organizaciónImplementado por organización. Aunque CDS_OrgDayOff tiene CDS_AppointmentConfig_ID, el motor actual no filtra por configuración.Debe filtrar por configuración cuando el servicio resuelva una configuración específica.
Día libre de empleadoImplementado con CDS_EmployeeDayOff.Se mantiene como bloqueo específico del empleado.
Horario del empleadoImplementado con CDS_EmployeeScheduleLine.Debe validarse después del horario macro de la configuración.
Horario macro de agendaPendiente. No existe aún una tabla equivalente a horario de configuración.Debe definir los días y rangos generales permitidos, por encima del horario del empleado.
Anticipación mínimaPendiente. Existe MinAdvanceHours, pero no se valida todavía.Debe bloquear citas creadas con menos horas de anticipación que las configuradas.
Anticipación máximaPendiente. Existe MaxAdvanceDays, pero no se valida todavía.Debe bloquear citas demasiado futuras.
Conflictos con citas existentesImplementado para estados Pending y Approved.Se mantiene como validación obligatoria.
Aprobación automática o forzadaPendiente. Existen campos de configuración y servicio, pero no se aplican en el evento.Debe resolverse en BeforeNew usando configuración y servicio.

Roadmap del motor

Lógica Backend

Callouts y Flujo de UI

CalloutAppointment ayuda al usuario a capturar una cita desde iDempiere sin reemplazar la validación final del backend.

Comportamiento de callouts

CampoComportamiento
CDS_AppointmentService_IDCopia precio y duración efectivos. Si existe empleado seleccionado, usa override de CDS_EmployeeService. Limpia slot y horas, pero no limpia empleado.
AppointmentDateLimpia slot, hora inicial y hora final. No limpia empleado ni servicio.
CDS_AppointmentSlot_IDCopia empleado, hora inicial, hora final, precio y duración desde el slot seleccionado.

Flujo recomendado en ventana

  1. Seleccionar el empleado que atenderá la cita.
  2. Seleccionar el servicio filtrado para ese empleado.
  3. Seleccionar la fecha de la cita.
  4. Ejecutar el proceso de generación de slots.
  5. Seleccionar el slot generado.
  6. Guardar la cita.

Importante: si un usuario modifica manualmente horas, precio o duración, el evento de modelo vuelve a validar la consistencia antes de guardar.

Lógica Backend

Procesos y Eventos

El plugin mantiene pocos procesos activos y concentra las reglas críticas en eventos de modelo.

Procesos activos

ProcesoUso
GenerateAppointmentSlotsGenera registros CDS_AppointmentSlot para el empleado, servicio y fecha seleccionados. Puede resolver valores desde la cita actual cuando se ejecuta desde la ventana.
ReopenAppointmentReabre una cita procesada cambiándola a pendiente y limpiando Processed mediante un contexto controlado.

Proceso GenerateAppointmentSlots

Este proceso se usa para crear horarios disponibles persistentes que luego pueden consultarse desde la ventana iDempiere o desde la API leyendo la tabla CDS_AppointmentSlot.

ParámetroRequeridoUso
AD_Org_IDSí, directo o resuelto desde la citaOrganización para cargar configuración y validar disponibilidad.
CDS_AppointmentEmployee_IDEmpleado para el cual se generan slots.
CDS_AppointmentService_IDServicio que define duración, precio e intervalo del slot.
AppointmentDateFecha para la cual se generan horarios disponibles.
CDS_Appointment_IDOpcionalSi se ejecuta desde una cita, permite resolver organización, empleado, servicio y fecha desde el registro actual.

Antes de generar nuevos slots, el proceso desactiva slots previos activos del usuario actual. Si hay una cita, desactiva los slots asociados a esa cita. Si no hay cita, desactiva slots del mismo usuario, empleado, servicio y fecha.

Uso recomendado: desde la ventana de cita se selecciona empleado, servicio y fecha; luego se ejecuta GenerateAppointmentSlots; finalmente se selecciona un registro de CDS_AppointmentSlot.

Proceso ReopenAppointment

Este proceso reabre una cita procesada para permitir correcciones administrativas controladas.

ParámetroRequeridoUso
CDS_Appointment_IDSí, directo o resuelto desde el registro actualCita procesada que se desea reabrir.

Si la cita ya está abierta, el proceso informa que no requiere reapertura. Si está procesada, activa un contexto temporal #CDS_ReopenAppointment, coloca Processed=N y cambia el estado a Pending.

Validación por evento actual

AppointmentModelValidator se ejecuta antes de crear o cambiar una cita. Para citas pendientes o aprobadas valida los datos mínimos y la disponibilidad real.

Estados y procesamiento actual

Roadmap de validaciones en eventos

Las siguientes reglas deben agregarse al evento para que el comportamiento sea consistente desde ventanas iDempiere y desde REST/API.

Validación pendienteMomento sugeridoRegla esperada
Resolver configuración desde servicioBeforeNew y BeforeChangeEl servicio debe indicar qué configuración de agenda aplica. La cita usa esa configuración para anticipación, horario macro y aprobación.
Servicio con una sola configuraciónAl guardar servicio o relación configuración-servicioUn servicio no debe estar asociado a más de una configuración activa.
Anticipación mínimaBeforeNew y generación de slotsSi StartDateTime está antes de ahora + MinAdvanceHours, la cita o slot debe bloquearse.
Anticipación máximaBeforeNew y generación de slotsSi StartDateTime supera hoy + MaxAdvanceDays, la cita o slot debe bloquearse.
Horario macro de configuraciónBeforeNew, BeforeChange y generación de slotsEl horario de agenda general debe contener el rango solicitado antes de evaluar el horario del empleado.
Forzar aprobaciónBeforeNewSi la configuración tiene ForceApproval=Y, la cita debe quedar pendiente aunque el servicio permita aprobación automática.
Autoaprobar si el servicio lo permiteBeforeNewSi AutoApproveIfServiceAllows=Y y el servicio no requiere aprobación, la cita puede quedar Approved.

Roadmap de workflows y correos

Además de las validaciones, falta definir workflows y plantillas de correo para notificar al cliente cuando cambie el estado de una cita.

Flujo pendienteDisparo sugeridoResultado esperado
Notificar cita aprobadaCambio de estado a Approved.Enviar correo al cliente con fecha, hora, servicio y empleado.
Notificar cita canceladaCambio de estado a Cancelled.Enviar correo al cliente con el motivo de cancelación cuando exista.
Notificar reprogramaciónCambio de fecha, hora o empleado.Enviar correo con el nuevo horario confirmado.
Recordatorio de citaProceso programado antes de StartDateTime.Enviar recordatorio al cliente según configuración.

También falta crear las plantillas de correo, definir destinatarios, configurar remitente, parametrizar cuándo enviar cada notificación y evitar reenvíos duplicados con campos de control si aplica.

Orden recomendado de validación

  1. Resolver servicio, empleado y organización.
  2. Resolver configuración de agenda desde el servicio.
  3. Aplicar reglas de anticipación mínima y máxima.
  4. Validar horario macro de configuración.
  5. Validar días libres de organización vinculados a la configuración.
  6. Validar relación empleado-servicio.
  7. Validar horario y días libres del empleado.
  8. Validar slot seleccionado.
  9. Validar conflictos con citas existentes.
  10. Resolver estado de aprobación: pendiente o aprobada.

Operación e Integración

Uso desde iDempiere, REST/API, instalación y 2Pack.

Operación e Integración

Uso desde REST/API

Los clientes externos pueden crear citas directamente en CDS_Appointment mediante la API REST estándar de iDempiere. No se requiere un proceso custom para crear la cita.

Idea clave: REST/API y ventana iDempiere comparten la misma seguridad funcional porque el evento de modelo valida el registro antes de guardarlo.

Flujo recomendado

  1. Consultar servicios activos en CDS_AppointmentService.
  2. Consultar empleados activos y sus relaciones en CDS_EmployeeService.
  3. Consultar o calcular disponibilidad usando la misma información de horarios y días libres.
  4. Crear un registro CDS_Appointment con cliente, empleado, servicio, fecha, hora inicial, hora final, precio, duración y estado.
  5. Dejar que AppointmentModelValidator valide consistencia, disponibilidad y conflictos.

Campos importantes

CampoUso
C_BPartner_IDCliente o tercero de la cita.
CDS_AppointmentEmployee_IDEmpleado que atiende.
CDS_AppointmentService_IDServicio solicitado.
AppointmentDateDía operativo de la cita.
StartDateTime / EndDateTimeRango exacto de atención.
Price / DurationMinutesValores efectivos de la cita, validados contra servicio/slot cuando aplique.
R_Request_IDReferencia opcional/manual si una implementación quiere vincular una solicitud. El código del plugin no depende de este campo.
Operación e Integración

Instalación y 2Pack

La instalación requiere desplegar el bundle OSGi del plugin y aplicar el 2Pack correspondiente en iDempiere 12.

2Packs incluidos

ArchivoUso
2Pack_1.0.0.zipPaquete inicial del diccionario de aplicación.
2Pack_1.0.1.zipPaquete actualizado con traducciones es_CO para campos, elementos, menús, ventanas, pestañas, procesos, parámetros, referencias y valores de lista.

Pasos de instalación

  1. Compilar y desplegar el bundle com.cdsoftware.appointment en iDempiere 12.
  2. Aplicar el 2Pack más reciente desde com.cdsoftware.appointment/META-INF.
  3. Reiniciar o refrescar iDempiere para activar servicios OSGi, factories, anotaciones, callouts, procesos y eventos.
  4. Configurar CDS_AppointmentConfig para la organización.
  5. Crear servicios en CDS_AppointmentService.
  6. Crear empleados en CDS_AppointmentEmployee.
  7. Relacionar empleados con servicios en CDS_EmployeeService.
  8. Configurar horarios semanales en CDS_EmployeeScheduleLine.
  9. Configurar días no disponibles en CDS_OrgDayOff o CDS_EmployeeDayOff.
  10. Probar la generación de slots y creación de citas desde la ventana.

Importante: después de aplicar cambios de diccionario que modifiquen columnas o referencias, se deben regenerar modelos y revisar que el código siga usando las constantes generadas.