up
This commit is contained in:
@@ -24,9 +24,9 @@ if (!in_array($prioCodigo, ['A', 'B', 'C', 'D', 'E', 'F'], true)) {
|
||||
jsonError('prioridad_codigo inválido. Use A, B, C, D, E o F.');
|
||||
}
|
||||
|
||||
$pacienteNombre = substr(trim($datos['paciente_nombre'] ?? ''), 0, 150);
|
||||
$pacienteCel = preg_replace('/[^0-9+\- ]/', '', $datos['paciente_cel'] ?? '');
|
||||
$pacienteCel = substr($pacienteCel, 0, 20);
|
||||
$pacienteDoc = substr(trim($datos['paciente_nombre'] ?? ''), 0, 150);
|
||||
$pacienteCel = preg_replace('/[^0-9+\- ]/', '', $datos['paciente_cel'] ?? '');
|
||||
$pacienteCel = substr($pacienteCel, 0, 20);
|
||||
|
||||
// ── Lógica principal (dentro de transacción para evitar race conditions) ──
|
||||
$pdo = db();
|
||||
@@ -49,6 +49,27 @@ try {
|
||||
|
||||
$prioridadId = (int) $prioridad['id'];
|
||||
|
||||
// Buscar paciente por número de documento en lab_pacientes
|
||||
$pacienteNombre = $pacienteDoc;
|
||||
$pacienteId = null;
|
||||
$pacienteTel = $pacienteCel; // fallback: celular del kiosko
|
||||
if ($pacienteDoc) {
|
||||
try {
|
||||
$stmtP = $pdo->prepare(
|
||||
'SELECT id, nombre_completo, telefono FROM lab_pacientes WHERE numero_documento = ? AND is_active = 1 LIMIT 1'
|
||||
);
|
||||
$stmtP->execute([$pacienteDoc]);
|
||||
$pacRow = $stmtP->fetch(PDO::FETCH_ASSOC);
|
||||
if ($pacRow) {
|
||||
$pacienteNombre = $pacRow['nombre_completo'];
|
||||
$pacienteId = (int) $pacRow['id'];
|
||||
$pacienteTel = $pacRow['telefono'] ?: $pacienteCel;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$pacienteNombre = $pacienteDoc;
|
||||
}
|
||||
}
|
||||
|
||||
// Correlativo independiente por prioridad (A-001, A-002... B-001, B-002... etc.)
|
||||
$numero = siguienteNumeroPorPrioridad($sesionId, $prioridadId);
|
||||
|
||||
@@ -57,10 +78,10 @@ try {
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO turnero_turnos
|
||||
(sesion_id, numero, codigo, prioridad_id, paciente_nombre, paciente_cel,
|
||||
(sesion_id, numero, codigo, prioridad_id, paciente_nombre, paciente_cel, paciente_id,
|
||||
estado, creado_at)
|
||||
VALUES
|
||||
(?, ?, ?, ?, ?, ?, "espera", NOW())'
|
||||
(?, ?, ?, ?, ?, ?, ?, "espera", NOW())'
|
||||
);
|
||||
$stmt->execute([
|
||||
$sesionId,
|
||||
@@ -69,6 +90,7 @@ try {
|
||||
$prioridadId,
|
||||
$pacienteNombre ?: null,
|
||||
$pacienteCel ?: null,
|
||||
$pacienteId,
|
||||
]);
|
||||
|
||||
$turnoId = (int) $pdo->lastInsertId();
|
||||
@@ -76,6 +98,69 @@ try {
|
||||
|
||||
notificarSSE($sesionId);
|
||||
|
||||
// ── Auto-crear consentimiento principal + enviar WhatsApp ──
|
||||
try {
|
||||
$stmtPc = $pdo->prepare(
|
||||
"SELECT id, nombre FROM lab_formularios WHERE is_principal = 1 AND tipo = 'consentimiento' AND is_active = 1 LIMIT 1"
|
||||
);
|
||||
$stmtPc->execute();
|
||||
$principalForm = $stmtPc->fetch(PDO::FETCH_ASSOC);
|
||||
if ($principalForm) {
|
||||
$tokenPrincipal = 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 = $pdo->prepare(
|
||||
"INSERT IGNORE INTO turnero_consentimientos (turno_id, formulario_id, token, estado)
|
||||
VALUES (?, ?, ?, 'pendiente')"
|
||||
);
|
||||
$stmtIns->execute([$turnoId, (int)$principalForm['id'], $tokenPrincipal]);
|
||||
|
||||
// Enviar WhatsApp si tenemos celular
|
||||
if ($pacienteTel) {
|
||||
$cel = preg_replace('/[\s\-\.]/', '', $pacienteTel);
|
||||
if (!str_starts_with($cel, '+')) {
|
||||
$cel = '+57' . ltrim($cel, '0');
|
||||
}
|
||||
$enlaceFirma = (defined('BASE_URL') ? rtrim(BASE_URL, '/') : '')
|
||||
. '/ver_formulario_enviado.php?token=' . urlencode($tokenPrincipal);
|
||||
$nombrePacWA = $pacienteNombre ?: 'Paciente';
|
||||
require_once __DIR__ . '/../../../services/WhatsAppService.php';
|
||||
try {
|
||||
$wa = new WhatsAppService();
|
||||
$wa->sendTemplateMessage(
|
||||
$cel,
|
||||
'consentimiento_turno',
|
||||
'es',
|
||||
[
|
||||
htmlspecialchars($nombrePacWA, ENT_QUOTES),
|
||||
htmlspecialchars($principalForm['nombre'], ENT_QUOTES),
|
||||
$codigo,
|
||||
],
|
||||
[$enlaceFirma]
|
||||
);
|
||||
} catch (\Throwable $eTmpl) {
|
||||
try {
|
||||
$mensajeTexto = "Hola {$nombrePacWA}, le informamos que para su turno *{$codigo}* "
|
||||
. "debe firmar el siguiente consentimiento informado:\n\n"
|
||||
. "*{$principalForm['nombre']}*\n\n"
|
||||
. "Puede firmarlo en el siguiente enlace:\n{$enlaceFirma}\n\n"
|
||||
. "Si ya firmó este documento presencial, ignore este mensaje.";
|
||||
$wa->sendTextMessage($cel, $mensajeTexto);
|
||||
} catch (\Throwable $eTxt) {
|
||||
// Silenciar error de WhatsApp, el turno ya se creó
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
// Silenciar error — el turno ya se creó exitosamente
|
||||
}
|
||||
|
||||
// Contar posición en la cola
|
||||
$stmt = $pdo->prepare(
|
||||
'
|
||||
|
||||
@@ -117,6 +117,28 @@ if ($lugarIdSol > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// 3c. Consentimiento principal de recepción (is_principal)
|
||||
$principalRow = null;
|
||||
try {
|
||||
$stmtPc = $pdo->prepare(
|
||||
"SELECT id AS formulario_id, nombre AS formulario_nombre
|
||||
FROM lab_formularios
|
||||
WHERE is_principal = 1 AND tipo = 'consentimiento' AND is_active = 1
|
||||
LIMIT 1"
|
||||
);
|
||||
$stmtPc->execute();
|
||||
$principalRow = $stmtPc->fetch(PDO::FETCH_ASSOC);
|
||||
} catch (\Throwable $e) {}
|
||||
if ($principalRow) {
|
||||
$yaExiste = false;
|
||||
foreach ($formulariosRequeridos as $fr) {
|
||||
if ((int)$fr['formulario_id'] === (int)$principalRow['formulario_id']) { $yaExiste = true; break; }
|
||||
}
|
||||
if (!$yaExiste) {
|
||||
$formulariosRequeridos[] = $principalRow;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($formulariosRequeridos)) {
|
||||
jsonOk(['consentimientos' => [], 'mensaje' => 'Ningún examen ni servicio requiere consentimiento.']);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* modules/turnero/api/set_principal_consent.php
|
||||
* POST { formulario_id: int | null }
|
||||
* Marca un lab_formularios como consentimiento principal de recepción.
|
||||
* Pasa null para desmarcar (ningún principal).
|
||||
* Solo UN formulario puede ser principal a la vez.
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$input = inputJson();
|
||||
$formularioId = isset($input['formulario_id']) ? (int) $input['formulario_id'] : null;
|
||||
|
||||
$pdo = db();
|
||||
|
||||
if ($formularioId) {
|
||||
// Verificar que el formulario existe y es tipo consentimiento
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id FROM lab_formularios WHERE id = ? AND tipo = 'consentimiento' AND is_active = 1"
|
||||
);
|
||||
$stmt->execute([$formularioId]);
|
||||
if (!$stmt->fetch()) {
|
||||
jsonError('Formulario no encontrado o no es un consentimiento activo.', 404);
|
||||
}
|
||||
}
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
// Quitar principal de todos
|
||||
$pdo->exec("UPDATE lab_formularios SET is_principal = 0 WHERE is_principal = 1");
|
||||
// Marcar el nuevo principal (si aplica)
|
||||
if ($formularioId) {
|
||||
$stmt = $pdo->prepare("UPDATE lab_formularios SET is_principal = 1 WHERE id = ?");
|
||||
$stmt->execute([$formularioId]);
|
||||
}
|
||||
$pdo->commit();
|
||||
jsonOk([
|
||||
'formulario_id' => $formularioId,
|
||||
], $formularioId ? 'Consentimiento principal actualizado' : 'Consentimiento principal desmarcado');
|
||||
} catch (\Throwable $e) {
|
||||
$pdo->rollBack();
|
||||
jsonError('Error al actualizar: ' . $e->getMessage(), 500);
|
||||
}
|
||||
Reference in New Issue
Block a user