Oleada B: fusion Expedientes en Pacientes (+chip sin visita 6m), sidebar colapsable SKEEN, edicion completa de citas, autocompletado de paciente, bloqueos excluidos de slots

This commit is contained in:
2026-09-11 10:38:08 +00:00
parent 0b45abc197
commit 4f49188deb
9 changed files with 295 additions and 65 deletions

View File

@@ -265,11 +265,18 @@ class SkeenCita(models.Model):
if b.all_day or (ini < b.time_to and fin > b.time_from):
raise ValidationError(_('El médico tiene un bloqueo (%s)') % (b.motivo or 'agenda bloqueada'))
def get_available_slots(self, date, servicio_id):
"""Retorna slots disponibles para una fecha y servicio"""
def get_available_slots(self, date, servicio_id, doctor_id=None):
"""Retorna slots disponibles para una fecha y servicio.
Con doctor_id, además excluye los horarios bloqueados de ese médico
(el usuario no debe poder elegir una hora bloqueada)."""
servicio = self.env['skeen.servicio'].browse(servicio_id)
duration = servicio.duration_min if servicio else 30
# Bloqueos del médico para la fecha (día completo y por rango)
bloqueos = self.env['skeen.cita.bloqueo'].search([
('date', '=', date),
] + ([('doctor_id', '=', doctor_id)] if doctor_id else []))
# Horario de la clínica: 8:00 AM a 7:00 PM
start_time = 8.0 # 8:00 AM
end_time = 19.0 # 7:00 PM
@@ -289,7 +296,11 @@ class SkeenCita(models.Model):
('datetime_start', '<', slot_end),
('datetime_end', '>', slot_start),
]
if not self.search(domain):
en_bloqueo = any(
b.all_day or (current < b.time_to and current + (duration / 60.0) > b.time_from)
for b in bloqueos
)
if not en_bloqueo and not self.search(domain):
slots.append({
'time': current,
'time_str': f"{int(current):02d}:{minutes:02d}",