Files
whatsapp/api/lab/save_domicilio.php
T
Lizandro GuarnizoandClaude Sonnet 4.6 f4da864db7 feat(turnero): toma prolongada secuencial + bloqueo muestras/cierre
- ver_formulario_enviado: auto-fill médico (nombres/especialidad/código) en datos_prefilled desde solicitud
- ver_formulario_enviado: canvases de toma progresiva bloqueados secuencialmente — solo el turno activo es firmable, los siguientes aparecen al expirar el countdown
- ver_formulario_enviado: countdown prominente con reloj grande, color dinámico, sonido (Web Audio) y vibración al llegar la hora
- lugar: bloquear cierre del modal durante toma progresiva activa (botón X deshabilitado hasta mp_completar)
- lugar: bloquear Finalizar atención si hay muestras pendientes sin decisión (recibida/rechazada)
- lugar: _syncBtnFinalizar combina consentimientos + muestras para el aviso y estado del botón
- lugar: restricción de usuario a lugar específico via turnero_lugar_id (admin_users) + bloqueo JS en confirmarLugar()
- migrations: turnero_lugar_id en admin_users para restringir bacteriólogos por usuario

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-08 21:16:07 -05:00

122 lines
5.3 KiB
PHP

<?php
/**
* POST /api/lab/save_domicilio.php
* Crea, actualiza o cambia estado de un domicilio.
* Body JSON:
* { id?, paciente_id, orden_id?, direccion, ciudad?, barrio?,
* indicaciones_dir?, fecha_programada, hora_programada?,
* tipo_servicio?, estado?,
* -- Para cambio de estado solamente:
* solo_estado?: true, nuevo_estado?, motivo_cancelacion?, ... }
*/
require_once __DIR__ . '/_helpers.php';
requireMethod('POST');
try {
$datos = inputJson();
$dom = new Domicilio();
$admin = adminId();
// ── Reprogramar ──
if (!empty($datos['id']) && !empty($datos['reprogramar'])) {
$id = (int)$datos['id'];
// Enfermero solo puede reprogramar domicilios que él mismo creó
if (userRole() === 'enfermero') {
$dbCheck = Database::getInstance();
$chk = $dbCheck->fetchOne("SELECT creado_por FROM lab_domicilios WHERE id = ?", [$id]);
if (!$chk || (int)($chk['creado_por'] ?? 0) !== adminId()) {
jsonError('Solo puedes reprogramar domicilios que tú mismo agendaste.');
}
}
$nuevaFecha = trim($datos['nueva_fecha'] ?? '');
$nuevaHora = trim($datos['nueva_hora'] ?? '');
$motivo = trim($datos['motivo'] ?? '');
if (!$nuevaFecha) jsonError('nueva_fecha es obligatoria');
$nuevoId = $dom->reprogramar($id, $nuevaFecha, $nuevaHora, $motivo, $admin);
jsonOk(['id_origen' => $id, 'id_nuevo' => $nuevoId], 'Domicilio reprogramado correctamente');
}
// Solo cambio de estado
if (!empty($datos['id']) && !empty($datos['solo_estado'])) {
$id = (int)$datos['id'];
$nuevoEstado = $datos['nuevo_estado'] ?? '';
$extras = array_filter([
'motivo_cancelacion' => $datos['motivo_cancelacion'] ?? null,
'fecha_reprogramada' => $datos['fecha_reprogramada'] ?? null,
'hora_llegada' => $datos['hora_llegada'] ?? null,
'hora_salida' => $datos['hora_salida'] ?? null,
'observaciones' => $datos['observaciones'] ?? null,
'muestras_tomadas' => $datos['muestras_tomadas'] ?? null,
]);
$dom->cambiarEstado($id, $nuevoEstado, $admin, $extras);
jsonOk(['id' => $id], 'Estado actualizado');
}
if (!empty($datos['id'])) {
// Actualización general
$id = (int)$datos['id'];
// Enfermero solo puede editar domicilios que él mismo creó
if (userRole() === 'enfermero') {
$dbCheck = Database::getInstance();
$chk = $dbCheck->fetchOne("SELECT creado_por FROM lab_domicilios WHERE id = ?", [$id]);
if (!$chk || (int)($chk['creado_por'] ?? 0) !== adminId()) {
jsonError('Solo puedes editar domicilios que tú mismo agendaste.');
}
}
unset($datos['id'], $datos['solo_estado']);
// Normalizar orden_id: vacío o 0 → null
if (isset($datos['orden_id']) && ($datos['orden_id'] === '' || (int)$datos['orden_id'] === 0)) {
$datos['orden_id'] = null;
}
$dom->actualizar($id, $datos, $admin);
jsonOk(['id' => $id], 'Domicilio actualizado correctamente');
} else {
// Creación
foreach (['paciente_id', 'direccion', 'fecha_programada'] as $req) {
if (empty($datos[$req])) {
jsonError("El campo $req es obligatorio");
}
}
// Validar formato mínimo de dirección
$dirVal = trim($datos['direccion'] ?? '');
if (strlen($dirVal) < 5) {
jsonError('La dirección es muy corta. Ingresa una dirección completa. Ej: Cra 15 # 32-10.');
}
// Normalizar orden_id: vacío o 0 → null (evita FK constraint)
if (isset($datos['orden_id']) && ($datos['orden_id'] === '' || (int)$datos['orden_id'] === 0)) {
$datos['orden_id'] = null;
}
// Si el creador es un enfermero y no vino enfermera_id, auto-asignarlo desde la sesión
if (empty($datos['enfermera_id']) && userRole() === 'enfermero') {
$eid = enfermeraId();
if ($eid) $datos['enfermera_id'] = $eid;
}
// Asignar número de orden D-YYYYMMDD-NNN si no viene uno
if (empty($datos['numero_orden'])) {
$pdo = db();
$prefix = 'D-' . date('Ymd') . '-';
$st = $pdo->prepare(
"SELECT MAX(CAST(SUBSTRING_INDEX(numero_orden, '-', -1) AS UNSIGNED)) AS ultimo
FROM lab_domicilios WHERE numero_orden LIKE ?"
);
$st->execute([$prefix . '%']);
$ultimo = (int)($st->fetch(\PDO::FETCH_ASSOC)['ultimo'] ?? 0);
$datos['numero_orden'] = $prefix . str_pad($ultimo + 1, 3, '0', STR_PAD_LEFT);
}
$id = $dom->crear($datos, $admin);
// Crear asignación automática si se indicó enfermera_id
if (!empty($datos['enfermera_id'])) {
$asig = new Asignacion();
$asig->asignar($id, (int)$datos['enfermera_id'], $admin);
}
jsonOk(['id' => $id], 'Domicilio creado correctamente');
}
} catch (InvalidArgumentException $e) {
jsonError($e->getMessage());
} catch (Exception $e) {
jsonError($e->getMessage(), 500);
}