get_consentimientos.php ahora incluye s.numero_orden en el SELECT. En lugar.php el número de orden aparece como badge de solo lectura en el header de la ficha, junto al código del turno, cuando la solicitud tiene número de orden asignado. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
226 lines
8.9 KiB
PHP
226 lines
8.9 KiB
PHP
<?php
|
|
/**
|
|
* GET /modules/turnero/api/get_consentimientos.php
|
|
* Retorna el estado actualizado de los consentimientos de un turno.
|
|
* Usado por lugar.php (polling cada 5 s) y recepcion.php.
|
|
* No requiere autenticación (las pantallas internas ya están protegidas).
|
|
*
|
|
* Query params:
|
|
* turno_id int requerido
|
|
* incluir_solicitud int opcional 1 → también retorna solicitud, paciente y exámenes
|
|
*/
|
|
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireMethod('GET');
|
|
|
|
$turnoId = isset($_GET['turno_id']) ? (int) $_GET['turno_id'] : 0;
|
|
$incluirSolicitud = isset($_GET['incluir_solicitud']) ? (bool)(int)$_GET['incluir_solicitud'] : false;
|
|
|
|
if ($turnoId <= 0) jsonError('turno_id inválido.');
|
|
|
|
$pdo = db();
|
|
|
|
// ── Verificar que el turno existe ─────────────────────────────
|
|
$stmt = $pdo->prepare("SELECT id, estado, lugar_destino_id FROM turnero_turnos WHERE id = ?");
|
|
$stmt->execute([$turnoId]);
|
|
$turno = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
if (!$turno) jsonError('Turno no encontrado.', 404);
|
|
|
|
// ── Consentimientos ───────────────────────────────────────────
|
|
$stmt = $pdo->prepare(
|
|
"SELECT tc.id,
|
|
tc.turno_id,
|
|
tc.formulario_id,
|
|
tc.token,
|
|
tc.estado,
|
|
tc.enviado_at,
|
|
tc.firmado_at,
|
|
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
|
tc.firmado_profesional_at,
|
|
f.nombre AS formulario_nombre,
|
|
f.esquema AS formulario_esquema
|
|
FROM turnero_consentimientos tc
|
|
LEFT JOIN lab_formularios f ON f.id = tc.formulario_id
|
|
WHERE tc.turno_id = ?
|
|
ORDER BY tc.id ASC"
|
|
);
|
|
$stmt->execute([$turnoId]);
|
|
$consentimientos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Compute requiere_firma_profesional from schema; strip raw esquema from response
|
|
foreach ($consentimientos as &$c) {
|
|
$esquema = $c['formulario_esquema'] ?? null;
|
|
$campos = [];
|
|
if ($esquema) {
|
|
$decoded = json_decode($esquema, true);
|
|
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
|
}
|
|
$c['requiere_firma_profesional'] = !empty(array_filter(
|
|
$campos,
|
|
fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'
|
|
));
|
|
unset($c['formulario_esquema']);
|
|
}
|
|
unset($c);
|
|
|
|
$respuesta = [
|
|
'turno_id' => $turnoId,
|
|
'turno_estado' => $turno['estado'],
|
|
'consentimientos' => $consentimientos,
|
|
];
|
|
|
|
// ── Datos adicionales si solicita solicitud ───────────────────
|
|
if ($incluirSolicitud) {
|
|
$stmt = $pdo->prepare(
|
|
"SELECT s.id, s.turno_id, s.paciente_id, s.lugar_id,
|
|
s.numero_orden,
|
|
s.total_cobrado, s.metodo_pago, s.observaciones, s.embarazada, s.solo_muestras, s.medico_id, s.creado_at,
|
|
l.nombre AS lugar_nombre,
|
|
CONCAT(m.nombres, ' ', m.apellidos) AS medico_nombre,
|
|
m.cod_especialidad AS medico_especialidad,
|
|
m.codigo AS medico_codigo
|
|
FROM turnero_solicitudes s
|
|
LEFT JOIN turnero_lugares l ON l.id = s.lugar_id
|
|
LEFT JOIN medicos m ON m.id = s.medico_id
|
|
WHERE s.turno_id = ?
|
|
LIMIT 1"
|
|
);
|
|
$stmt->execute([$turnoId]);
|
|
$solicitud = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
|
|
$paciente = null;
|
|
$examenes = [];
|
|
|
|
if ($solicitud) {
|
|
// Paciente
|
|
$stmt = $pdo->prepare(
|
|
"SELECT id, nombre_completo, tipo_documento, numero_documento,
|
|
fecha_nacimiento, telefono
|
|
FROM lab_pacientes
|
|
WHERE id = ?"
|
|
);
|
|
$stmt->execute([$solicitud['paciente_id']]);
|
|
$paciente = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
|
|
|
|
// Exámenes
|
|
$stmt = $pdo->prepare(
|
|
"SELECT et.id, et.codigo, et.nombre, et.categoria
|
|
FROM turnero_examen_items tei
|
|
JOIN exam_tipos et ON et.id = tei.exam_tipo_id
|
|
WHERE tei.solicitud_id = ?
|
|
ORDER BY et.categoria, et.nombre"
|
|
);
|
|
$stmt->execute([$solicitud['id']]);
|
|
$examenes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Auto-crear consentimientos requeridos desde DOS fuentes:
|
|
// 1. Por examen → exam_tipo_consentimientos
|
|
// 2. Por lugar → turnero_lugar_consentimientos
|
|
$requeridos = [];
|
|
$vistosFIds = [];
|
|
|
|
// Fuente 1: examen
|
|
if (!empty($examenes)) {
|
|
$examIds = array_column($examenes, 'id');
|
|
$ph = implode(',', array_fill(0, count($examIds), '?'));
|
|
$stmtE = $pdo->prepare(
|
|
"SELECT DISTINCT etc.formulario_id, f.nombre AS formulario_nombre
|
|
FROM exam_tipo_consentimientos etc
|
|
JOIN lab_formularios f ON f.id = etc.formulario_id
|
|
WHERE etc.exam_tipo_id IN ($ph) AND f.is_active = 1"
|
|
);
|
|
$stmtE->execute($examIds);
|
|
foreach ($stmtE->fetchAll(PDO::FETCH_ASSOC) as $r) {
|
|
$fid = (int)$r['formulario_id'];
|
|
if (!in_array($fid, $vistosFIds, true)) {
|
|
$requeridos[] = $r;
|
|
$vistosFIds[] = $fid;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fuente 2: lugar destino del turno
|
|
$lugarDestinoId = (int)($turno['lugar_destino_id'] ?? 0);
|
|
if ($lugarDestinoId) {
|
|
$stmtL = $pdo->prepare(
|
|
"SELECT DISTINCT tlc.formulario_id, f.nombre AS formulario_nombre
|
|
FROM turnero_lugar_consentimientos tlc
|
|
JOIN lab_formularios f ON f.id = tlc.formulario_id
|
|
WHERE tlc.lugar_id = ? AND f.is_active = 1"
|
|
);
|
|
$stmtL->execute([$lugarDestinoId]);
|
|
foreach ($stmtL->fetchAll(PDO::FETCH_ASSOC) as $r) {
|
|
$fid = (int)$r['formulario_id'];
|
|
if (!in_array($fid, $vistosFIds, true)) {
|
|
$requeridos[] = $r;
|
|
$vistosFIds[] = $fid;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Auto-crear los registros que falten
|
|
if (!empty($requeridos)) {
|
|
$existFormIds = array_map('intval', array_column($consentimientos, 'formulario_id'));
|
|
$stmtIns = $pdo->prepare(
|
|
"INSERT IGNORE INTO turnero_consentimientos
|
|
(turno_id, formulario_id, token, estado)
|
|
VALUES (?, ?, ?, 'pendiente')"
|
|
);
|
|
$creados = 0;
|
|
foreach ($requeridos as $r) {
|
|
if (!in_array((int)$r['formulario_id'], $existFormIds, true)) {
|
|
$token = sprintf(
|
|
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
|
|
mt_rand(0,0xffff), mt_rand(0,0xffff),
|
|
mt_rand(0,0xffff),
|
|
mt_rand(0,0x0fff)|0x4000,
|
|
mt_rand(0,0x3fff)|0x8000,
|
|
mt_rand(0,0xffff), mt_rand(0,0xffff), mt_rand(0,0xffff)
|
|
);
|
|
$stmtIns->execute([$turnoId, (int)$r['formulario_id'], $token]);
|
|
$creados++;
|
|
}
|
|
}
|
|
|
|
// Re-leer si se crearon nuevos registros
|
|
if ($creados > 0) {
|
|
$stmtC = $pdo->prepare(
|
|
"SELECT tc.id, tc.turno_id, tc.formulario_id, tc.token,
|
|
tc.estado, tc.enviado_at, tc.firmado_at,
|
|
(tc.firma_profesional_svg IS NOT NULL) AS tiene_firma_profesional,
|
|
tc.firmado_profesional_at,
|
|
f.nombre AS formulario_nombre,
|
|
f.esquema AS formulario_esquema
|
|
FROM turnero_consentimientos tc
|
|
LEFT JOIN lab_formularios f ON f.id = tc.formulario_id
|
|
WHERE tc.turno_id = ?
|
|
ORDER BY tc.id ASC"
|
|
);
|
|
$stmtC->execute([$turnoId]);
|
|
$consentimientos = $stmtC->fetchAll(PDO::FETCH_ASSOC);
|
|
foreach ($consentimientos as &$c) {
|
|
$esquema = $c['formulario_esquema'] ?? null;
|
|
$campos = [];
|
|
if ($esquema) {
|
|
$decoded = json_decode($esquema, true);
|
|
$campos = is_array($decoded) ? $decoded : ($decoded['campos'] ?? []);
|
|
}
|
|
$c['requiere_firma_profesional'] = !empty(array_filter(
|
|
$campos,
|
|
fn($f) => ($f['tipo'] ?? '') === 'firma_profesional'
|
|
));
|
|
unset($c['formulario_esquema']);
|
|
}
|
|
unset($c);
|
|
$respuesta['consentimientos'] = $consentimientos;
|
|
}
|
|
}
|
|
}
|
|
|
|
$respuesta['solicitud'] = $solicitud;
|
|
$respuesta['paciente'] = $paciente;
|
|
$respuesta['examenes'] = $examenes;
|
|
}
|
|
|
|
jsonOk($respuesta);
|