Files
whatsapp/modules/lab_examenes/api/save.php
T
Lizandro GuarnizoandClaude Opus 5 71c9dfd424 Documentación: diagramas, kiosko y chat, catálogos, respaldos y endpoints documentados
Diagramas en texto dentro de bloques de código, en vez de capturas: se editan
como texto, no pesan en el repositorio y no quedan desactualizados solos. Se
agregan el recorrido de un turno, quién firma cada consentimiento, el paso de
una muestra pendiente entre visitas y la línea de tiempo de las tomas seriadas.

Páginas nuevas del manual: kiosko y pantallas de TV (las dos que funcionan sin
nadie operándolas), y chat de WhatsApp, que explica por qué el bot deja de
responder cuando un operador toma la conversación y de dónde sale el límite de
24 horas.

Páginas técnicas nuevas: registro de exámenes, y los catálogos del laboratorio
agrupados en una sola página por compartir la misma forma. Operación suma
respaldos y recuperación, incluyendo qué datos históricos no son recuperables.

Los 10 endpoints que no tenían comentario de cabecera ahora lo tienen, así que
la tabla generada por {{endpoints}} queda completa: 83 de 83.

DOCUMENTACION_LAB.md y README_LAB.md quedan como puntero al módulo;
WEBHOOK_ENDPOINTS.md se elimina por estar ya migrado a la sección técnica.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 10:49:02 -05:00

75 lines
3.5 KiB
PHP

<?php
/**
* POST — Crea o actualiza un examen del catálogo. Requiere administrador.
*/
require_once __DIR__ . '/_helpers.php';
requireAdmin();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') jsonError('Método no permitido', 405);
$d = inputJson();
$id = (int)($d['id'] ?? 0);
if (!empty($d['_delete'])) {
if (!$id) jsonError('ID requerido');
$pdo = db();
$s = $pdo->prepare('SELECT COUNT(*) FROM turnero_examen_items WHERE exam_tipo_id = ?');
$s->execute([$id]);
if ($s->fetchColumn() > 0) jsonError('Hay solicitudes con este examen. Desactívelo en su lugar.');
$pdo->prepare('DELETE FROM exam_tipo_consentimientos WHERE exam_tipo_id = ?')->execute([$id]);
$pdo->prepare('DELETE FROM exam_tipos WHERE id = ?')->execute([$id]);
jsonOk([], 'Examen eliminado');
}
$codigo = strtoupper(trim($d['codigo'] ?? ''));
$nombre = trim($d['nombre'] ?? '');
$categoria = trim($d['categoria'] ?? '') ?: null;
$cups = trim($d['cups'] ?? '') ?: null;
$cod_prot = trim($d['cod_protocolo'] ?? '') ?: null;
$tipo_m = trim($d['tipo_muestra'] ?? '') ?: null;
$nivel = isset($d['nivel']) && $d['nivel'] !== '' ? (int)$d['nivel'] : null;
$abrev = trim($d['abreviatura'] ?? '') ?: null;
$seremite = (int)($d['seremite'] ?? 0);
$serecibe = trim($d['serecibe'] ?? '') ?: null;
$activo = (int)($d['activo'] ?? 1);
$req_ayuno = (int)($d['requiere_ayuno'] ?? 0);
$horas_ayuno = isset($d['horas_ayuno']) && $d['horas_ayuno'] !== '' ? (int)$d['horas_ayuno'] : null;
$instruc = trim($d['instrucciones'] ?? '') ?: null;
$formIds = array_values(array_unique(array_filter(array_map('intval', (array)($d['form_ids'] ?? [])))));
if ($codigo === '') jsonError('El código es requerido');
if ($nombre === '') jsonError('El nombre es requerido');
if (strlen($codigo) > 20) jsonError('Código máximo 20 caracteres');
$pdo = db();
$pdo->beginTransaction();
try {
if ($id) {
$pdo->prepare(
'UPDATE exam_tipos SET codigo=?,nombre=?,categoria=?,cups=?,cod_protocolo=?,tipo_muestra=?,
nivel=?,abreviatura=?,seremite=?,serecibe=?,activo=?,requiere_ayuno=?,horas_ayuno=?,instrucciones=?
WHERE id=?'
)->execute([$codigo,$nombre,$categoria,$cups,$cod_prot,$tipo_m,
$nivel,$abrev,$seremite,$serecibe,$activo,$req_ayuno,$horas_ayuno,$instruc,$id]);
$examId = $id;
} else {
$pdo->prepare(
'INSERT INTO exam_tipos (codigo,nombre,categoria,cups,cod_protocolo,tipo_muestra,
nivel,abreviatura,seremite,serecibe,activo,codigo_legacy,requiere_ayuno,horas_ayuno,instrucciones)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
)->execute([$codigo,$nombre,$categoria,$cups,$cod_prot,$tipo_m,
$nivel,$abrev,$seremite,$serecibe,$activo,$codigo,$req_ayuno,$horas_ayuno,$instruc]);
$examId = (int)$pdo->lastInsertId();
}
$pdo->prepare('DELETE FROM exam_tipo_consentimientos WHERE exam_tipo_id = ?')->execute([$examId]);
$ins = $pdo->prepare('INSERT INTO exam_tipo_consentimientos (exam_tipo_id, formulario_id) VALUES (?,?)');
foreach ($formIds as $fid) { $ins->execute([$examId, $fid]); }
$pdo->commit();
jsonOk(['id' => $examId], $id ? 'Examen actualizado' : 'Examen creado');
} catch (\Throwable $e) {
$pdo->rollBack();
if ($e->getCode() === '23000') jsonError('Ya existe un examen con ese código');
jsonError('Error: ' . $e->getMessage(), 500);
}