up
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/create_turno.php
|
||||
* Genera un nuevo turno desde el kiosko o recepción.
|
||||
* No requiere login (kiosko es público).
|
||||
*
|
||||
* Body JSON:
|
||||
* prioridad_codigo string requerido "A"|"B"|"C"|"D"|"E"|"F"
|
||||
* paciente_nombre string opcional
|
||||
* paciente_cel string opcional
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
|
||||
// Este endpoint es público (kiosko no requiere login)
|
||||
// Solo validamos CSRF básico: debe ser POST con JSON
|
||||
|
||||
$datos = inputJson();
|
||||
|
||||
// ── Validación ────────────────────────────────────────────────
|
||||
$prioCodigo = strtoupper(trim($datos['prioridad_codigo'] ?? ''));
|
||||
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);
|
||||
|
||||
// ── Lógica principal (dentro de transacción para evitar race conditions) ──
|
||||
$pdo = db();
|
||||
$pdo->beginTransaction();
|
||||
|
||||
try {
|
||||
$sesionId = obtenerOCrearSesionHoy();
|
||||
$numero = siguienteNumero($sesionId);
|
||||
|
||||
// Buscar prioridad_id
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT id FROM turnero_prioridades WHERE codigo = ? AND activo = 1 LIMIT 1'
|
||||
);
|
||||
$stmt->execute([$prioCodigo]);
|
||||
$prioridad = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$prioridad) {
|
||||
$pdo->rollBack();
|
||||
jsonError("La prioridad '$prioCodigo' no existe o no está activa.", 422);
|
||||
}
|
||||
|
||||
$prioridadId = (int) $prioridad['id'];
|
||||
|
||||
// Código visual: "A001", "E042", etc.
|
||||
$codigo = $prioCodigo . str_pad($numero, 3, '0', STR_PAD_LEFT);
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO turnero_turnos
|
||||
(sesion_id, numero, codigo, prioridad_id, paciente_nombre, paciente_cel,
|
||||
estado, creado_at)
|
||||
VALUES
|
||||
(?, ?, ?, ?, ?, ?, "espera", NOW())'
|
||||
);
|
||||
$stmt->execute([
|
||||
$sesionId,
|
||||
$numero,
|
||||
$codigo,
|
||||
$prioridadId,
|
||||
$pacienteNombre ?: null,
|
||||
$pacienteCel ?: null,
|
||||
]);
|
||||
|
||||
$turnoId = (int) $pdo->lastInsertId();
|
||||
$pdo->commit();
|
||||
|
||||
notificarSSE($sesionId);
|
||||
|
||||
// Contar posición en la cola
|
||||
$stmt = $pdo->prepare(
|
||||
'
|
||||
SELECT COUNT(*) AS posicion
|
||||
FROM turnero_turnos t
|
||||
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
||||
WHERE t.estado = "espera"
|
||||
AND t.sesion_id = ?
|
||||
AND (
|
||||
p.orden_peso < (SELECT orden_peso FROM turnero_prioridades WHERE id = ?)
|
||||
OR (
|
||||
p.orden_peso = (SELECT orden_peso FROM turnero_prioridades WHERE id = ?)
|
||||
AND t.creado_at < (SELECT creado_at FROM turnero_turnos WHERE id = ?)
|
||||
)
|
||||
)
|
||||
'
|
||||
);
|
||||
$stmt->execute([$sesionId, $prioridadId, $prioridadId, $turnoId]);
|
||||
$posicion = (int) $stmt->fetchColumn() + 1;
|
||||
|
||||
jsonOk([
|
||||
'turno' => [
|
||||
'id' => $turnoId,
|
||||
'codigo' => $codigo,
|
||||
'numero' => $numero,
|
||||
'prioridad_codigo' => $prioCodigo,
|
||||
'posicion_cola' => $posicion,
|
||||
'sesion_id' => $sesionId,
|
||||
],
|
||||
], "Turno $codigo asignado correctamente");
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
jsonError('Error al crear el turno: ' . $e->getMessage(), 500);
|
||||
}
|
||||
Reference in New Issue
Block a user