192 lines
6.9 KiB
PHP
192 lines
6.9 KiB
PHP
<?php
|
|
/**
|
|
* GET /modules/turnero/api/get_display_global.php
|
|
* Devuelve el estado GLOBAL del sistema para la pantalla TV unificada.
|
|
* Retorna: turno activo en Recepción + turno activo en cada Lugar + cola.
|
|
* No requiere autenticación (acceso público).
|
|
*/
|
|
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireMethod('GET');
|
|
|
|
$pdo = db();
|
|
|
|
// Si no hay sesión hoy o está cerrada → $sesionId = 0 (queries devuelven vacío).
|
|
$_ses = sesionHoy();
|
|
$sesionCerrada = (!$_ses || $_ses['fin_at'] !== null);
|
|
$sesionId = ($sesionCerrada) ? 0 : (int)$_ses['id'];
|
|
|
|
// ── 1. Escritorios de Recepción activos + su turno en_recepcion ─
|
|
// Cada escritorio puede tener un turno distinto (varios recepcionistas).
|
|
$stmtDesks = $pdo->query(
|
|
"SELECT id, nombre, sort_order
|
|
FROM turnero_lugares
|
|
WHERE activo = 1 AND tipo = 'recepcion'
|
|
ORDER BY sort_order ASC"
|
|
);
|
|
$escritoriosRec = $stmtDesks->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$activosRecepcion = [];
|
|
foreach ($escritoriosRec as $desk) {
|
|
// El turno activo de este escritorio: el más reciente asociado a él
|
|
$stmtT = $pdo->prepare(
|
|
"SELECT t.id,
|
|
t.codigo,
|
|
t.numero,
|
|
t.estado,
|
|
t.paciente_nombre,
|
|
t.paciente_id,
|
|
t.llamado_recepcion_at AS llamado_at,
|
|
p.codigo AS prioridad_codigo,
|
|
p.nombre AS prioridad_nombre,
|
|
p.color AS prioridad_color
|
|
FROM turnero_turnos t
|
|
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
|
WHERE t.sesion_id = ?
|
|
AND t.estado = 'en_recepcion'
|
|
AND (t.recepcion_desk_id = ? OR t.recepcion_desk_id IS NULL)
|
|
ORDER BY t.llamado_recepcion_at DESC
|
|
LIMIT 1"
|
|
);
|
|
$stmtT->execute([$sesionId, (int)$desk['id']]);
|
|
$turno = $stmtT->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
|
|
$activosRecepcion[] = [
|
|
'desk_id' => (int)$desk['id'],
|
|
'desk_nombre'=> $desk['nombre'],
|
|
'sort_order' => (int)$desk['sort_order'],
|
|
'turno' => $turno,
|
|
];
|
|
}
|
|
|
|
// Si no hay escritorios configurados, mostrar todos en_recepcion sin desk
|
|
if (empty($escritoriosRec)) {
|
|
$stmtRec = $pdo->prepare(
|
|
"SELECT t.id,
|
|
t.codigo,
|
|
t.numero,
|
|
t.estado,
|
|
t.paciente_nombre,
|
|
t.paciente_id,
|
|
t.llamado_recepcion_at AS llamado_at,
|
|
p.codigo AS prioridad_codigo,
|
|
p.nombre AS prioridad_nombre,
|
|
p.color AS prioridad_color
|
|
FROM turnero_turnos t
|
|
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
|
WHERE t.sesion_id = ?
|
|
AND t.estado = 'en_recepcion'
|
|
ORDER BY t.llamado_recepcion_at DESC"
|
|
);
|
|
$stmtRec->execute([$sesionId]);
|
|
foreach ($stmtRec->fetchAll(PDO::FETCH_ASSOC) as $i => $t) {
|
|
$activosRecepcion[] = [
|
|
'desk_id' => 0,
|
|
'desk_nombre'=> 'Recepción ' . ($i + 1),
|
|
'sort_order' => $i,
|
|
'turno' => $t,
|
|
];
|
|
}
|
|
// Si no hay ninguno activo, mostrar un panel vacío
|
|
if (empty($activosRecepcion)) {
|
|
$activosRecepcion[] = ['desk_id' => 0, 'desk_nombre' => 'Recepción', 'sort_order' => 0, 'turno' => null];
|
|
}
|
|
}
|
|
|
|
// ── 2. Estaciones de Muestras activas + su turno ─────────────
|
|
$stmtLugares = $pdo->query(
|
|
"SELECT id, nombre, sort_order
|
|
FROM turnero_lugares
|
|
WHERE activo = 1 AND tipo = 'muestras'
|
|
ORDER BY sort_order ASC"
|
|
);
|
|
$lugares = $stmtLugares->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
$lugaresActivos = [];
|
|
foreach ($lugares as $lugar) {
|
|
$stmtActivo = $pdo->prepare(
|
|
"SELECT t.id,
|
|
t.codigo,
|
|
t.numero,
|
|
t.estado,
|
|
t.paciente_nombre,
|
|
t.paciente_id,
|
|
t.llamado_lugar_at AS llamado_at,
|
|
p.codigo AS prioridad_codigo,
|
|
p.nombre AS prioridad_nombre,
|
|
p.color AS prioridad_color
|
|
FROM turnero_turnos t
|
|
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
|
WHERE t.sesion_id = ?
|
|
AND t.estado = 'en_servicio'
|
|
AND t.lugar_destino_id = ?
|
|
ORDER BY t.llamado_lugar_at DESC
|
|
LIMIT 1"
|
|
);
|
|
$stmtActivo->execute([$sesionId, (int)$lugar['id']]);
|
|
$turnoActivo = $stmtActivo->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
|
|
$lugaresActivos[] = [
|
|
'lugar_id' => (int)$lugar['id'],
|
|
'lugar_nombre'=> $lugar['nombre'],
|
|
'sort_order' => (int)$lugar['sort_order'],
|
|
'turno' => $turnoActivo,
|
|
];
|
|
}
|
|
|
|
// ── 3. Cola en espera (pendientes por llamar) ─────────────────
|
|
$stmtCola = $pdo->prepare(
|
|
"SELECT t.id,
|
|
t.codigo,
|
|
t.numero,
|
|
t.estado,
|
|
t.paciente_nombre,
|
|
t.creado_at,
|
|
p.codigo AS prioridad_codigo,
|
|
p.nombre AS prioridad_nombre,
|
|
p.color AS prioridad_color,
|
|
p.orden_peso
|
|
FROM turnero_turnos t
|
|
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
|
WHERE t.sesion_id = ?
|
|
AND t.estado = 'espera'
|
|
ORDER BY p.orden_peso ASC, t.creado_at ASC"
|
|
);
|
|
$stmtCola->execute([$sesionId]);
|
|
$cola = $stmtCola->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// ── 4. Estadísticas ───────────────────────────────────────────
|
|
$stmtStats = $pdo->prepare(
|
|
"SELECT
|
|
COUNT(*) AS total,
|
|
SUM(estado = 'espera') AS en_espera,
|
|
SUM(estado = 'en_recepcion') AS en_recepcion,
|
|
SUM(estado = 'en_espera_lugar') AS en_espera_lugar,
|
|
SUM(estado = 'en_servicio') AS en_servicio,
|
|
SUM(estado IN ('en_recepcion','en_espera_lugar',
|
|
'en_servicio')) AS en_atencion,
|
|
SUM(estado = 'finalizado') AS finalizados,
|
|
SUM(estado IN ('ausente','cancelado')) AS no_atendidos,
|
|
SEC_TO_TIME(
|
|
AVG(
|
|
CASE WHEN fin_lugar_at IS NOT NULL AND creado_at IS NOT NULL
|
|
THEN TIMESTAMPDIFF(SECOND, creado_at, fin_lugar_at)
|
|
ELSE NULL END
|
|
)
|
|
) AS tiempo_promedio_atencion
|
|
FROM turnero_turnos
|
|
WHERE sesion_id = ?"
|
|
);
|
|
$stmtStats->execute([$sesionId]);
|
|
$stats = $stmtStats->fetch(PDO::FETCH_ASSOC);
|
|
|
|
jsonOk([
|
|
'sesion_id' => $sesionId,
|
|
'sesion_cerrada' => $sesionCerrada,
|
|
'activos_recepcion'=> $activosRecepcion, // array de desks con su turno
|
|
'lugares' => $lugaresActivos, // array de estaciones de muestras
|
|
'cola' => $cola,
|
|
'stats' => $stats,
|
|
'timestamp' => date('c'),
|
|
]);
|