up
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* POST /modules/turnero/api/llamar_turno.php
|
||||
* Llama el siguiente turno de una cola con el motor de prioridades.
|
||||
* Requiere login + módulo turnero.
|
||||
*
|
||||
* Body JSON:
|
||||
* area string requerido "recepcion" | "lugar"
|
||||
* lugar_id int requerido si area = "lugar"
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
requireMethod('POST');
|
||||
requireTurnero();
|
||||
|
||||
$datos = inputJson();
|
||||
$area = $datos['area'] ?? '';
|
||||
$lugarId = isset($datos['lugar_id']) ? (int) $datos['lugar_id'] : null;
|
||||
|
||||
// ── Validación ────────────────────────────────────────────────
|
||||
if (!in_array($area, ['recepcion', 'lugar'], true)) {
|
||||
jsonError('area debe ser "recepcion" o "lugar".');
|
||||
}
|
||||
if ($area === 'lugar' && !$lugarId) {
|
||||
jsonError('lugar_id es obligatorio cuando area = "lugar".');
|
||||
}
|
||||
|
||||
$pdo = db();
|
||||
$pdo->beginTransaction();
|
||||
|
||||
try {
|
||||
if ($area === 'recepcion') {
|
||||
// Cola recepción: turnos en estado 'espera' sin filtro de lugar
|
||||
$turno = siguienteTurnoEnCola('espera');
|
||||
|
||||
if (!$turno) {
|
||||
$pdo->rollBack();
|
||||
jsonOk(['turno' => null], 'Cola de recepción vacía');
|
||||
}
|
||||
|
||||
// Actualizar estado + timestamp
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE turnero_turnos
|
||||
SET estado = "en_recepcion",
|
||||
llamado_recepcion_at = NOW(),
|
||||
inicio_recepcion_at = NOW(),
|
||||
atendido_recepcion_por = ?
|
||||
WHERE id = ? AND estado = "espera"'
|
||||
);
|
||||
$stmt->execute([adminId(), $turno['id']]);
|
||||
|
||||
if ($stmt->rowCount() === 0) {
|
||||
// Otro proceso lo tomó primero (race condition)
|
||||
$pdo->rollBack();
|
||||
jsonError('El turno ya fue tomado por otro operador. Intente de nuevo.', 409);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Cola de un Lugar específico: turnos 'en_espera_lugar' asignados a ese lugar
|
||||
$turno = siguienteTurnoEnCola('en_espera_lugar', $lugarId);
|
||||
|
||||
if (!$turno) {
|
||||
$pdo->rollBack();
|
||||
jsonOk(['turno' => null], 'Cola del lugar vacía');
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE turnero_turnos
|
||||
SET estado = "en_servicio",
|
||||
llamado_lugar_at = NOW(),
|
||||
inicio_lugar_at = NOW(),
|
||||
atendido_lugar_por = ?
|
||||
WHERE id = ? AND estado = "en_espera_lugar"'
|
||||
);
|
||||
$stmt->execute([adminId(), $turno['id']]);
|
||||
|
||||
if ($stmt->rowCount() === 0) {
|
||||
$pdo->rollBack();
|
||||
jsonError('El turno ya fue tomado por otro operador. Intente de nuevo.', 409);
|
||||
}
|
||||
}
|
||||
|
||||
// Refrescar datos del turno actualizado
|
||||
$stmt = $pdo->prepare(
|
||||
'SELECT t.*,
|
||||
p.codigo AS prioridad_codigo,
|
||||
p.nombre AS prioridad_nombre,
|
||||
p.color AS prioridad_color
|
||||
FROM turnero_turnos t
|
||||
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
||||
WHERE t.id = ?'
|
||||
);
|
||||
$stmt->execute([$turno['id']]);
|
||||
$turnoActualizado = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$pdo->commit();
|
||||
notificarSSE((int) $turnoActualizado['sesion_id']);
|
||||
|
||||
jsonOk(['turno' => $turnoActualizado], "Turno {$turnoActualizado['codigo']} llamado");
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
jsonError('Error al llamar turno: ' . $e->getMessage(), 500);
|
||||
}
|
||||
Reference in New Issue
Block a user