- LIA: saludo de voz al abrir (1x/día), auto-escucha 3s, olas animadas - Gráfica de barras (Chart.js) con facturación real + proyección lineal - Exportar a Excel (.xls con HTML table, se abre directo en Excel) - Botón "Informe WA": envía resumen del día por WhatsApp a número elegido - Diseño accesible: texto más grande, botones claros para usuario adulto Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
109 lines
4.6 KiB
PHP
109 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* GET export_excel.php
|
|
* Exporta el resumen del día como .xls (HTML table, abre en Excel).
|
|
*/
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireTurnero();
|
|
requireMethod('GET');
|
|
|
|
$pdo = db();
|
|
$hoy = trim($_GET['fecha'] ?? date('Y-m-d'));
|
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $hoy)) $hoy = date('Y-m-d');
|
|
|
|
$ses = $pdo->prepare("SELECT id FROM turnero_sesiones WHERE fecha = ? LIMIT 1");
|
|
$ses->execute([$hoy]);
|
|
$sesion = $ses->fetch(PDO::FETCH_ASSOC);
|
|
|
|
$turnos = [];
|
|
if ($sesion) {
|
|
$sesId = (int)$sesion['id'];
|
|
$stmt = $pdo->prepare(
|
|
"SELECT t.codigo, p.codigo AS prioridad, t.estado,
|
|
COALESCE(sp.nombre_completo, t.paciente_nombre) AS paciente,
|
|
sp.tipo_documento AS tipo_doc, sp.numero_documento AS num_doc,
|
|
t.paciente_cel AS celular,
|
|
l.nombre AS lugar,
|
|
ur.full_name AS recepcionista,
|
|
ul.full_name AS bacteriologo,
|
|
ts.total_cobrado AS cobrado, ts.metodo_pago,
|
|
GROUP_CONCAT(DISTINCT et.nombre ORDER BY et.nombre SEPARATOR ', ') AS examenes,
|
|
ROUND(TIMESTAMPDIFF(SECOND, t.creado_at, COALESCE(t.inicio_recepcion_at, t.fin_recepcion_at)) / 60, 1) AS espera_min,
|
|
ROUND(TIMESTAMPDIFF(SECOND, t.inicio_lugar_at, COALESCE(t.fin_lugar_at, NOW())) / 60, 1) AS servicio_min,
|
|
ROUND(TIMESTAMPDIFF(SECOND, t.creado_at, t.fin_lugar_at) / 60, 1) AS total_min,
|
|
t.creado_at
|
|
FROM turnero_turnos t
|
|
JOIN turnero_prioridades p ON p.id = t.prioridad_id
|
|
LEFT JOIN turnero_lugares l ON l.id = t.lugar_destino_id
|
|
LEFT JOIN turnero_solicitudes ts ON ts.turno_id = t.id
|
|
LEFT JOIN turnero_examen_items tei ON tei.solicitud_id = ts.id
|
|
LEFT JOIN exam_tipos et ON et.id = tei.exam_tipo_id
|
|
LEFT JOIN lab_pacientes sp ON sp.id = ts.paciente_id
|
|
LEFT JOIN admin_users ur ON ur.id = t.atendido_recepcion_por
|
|
LEFT JOIN admin_users ul ON ul.id = t.atendido_lugar_por
|
|
WHERE t.sesion_id = ?
|
|
GROUP BY t.id ORDER BY t.numero ASC"
|
|
);
|
|
$stmt->execute([$sesId]);
|
|
$turnos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
}
|
|
|
|
$fecha = date('d/m/Y', strtotime($hoy));
|
|
$archivo = 'informe-turnero-' . $hoy . '.xls';
|
|
|
|
header('Content-Type: application/vnd.ms-excel; charset=utf-8');
|
|
header('Content-Disposition: attachment; filename="' . $archivo . '"');
|
|
header('Cache-Control: no-cache');
|
|
|
|
$estados = [
|
|
'finalizado'=>'Finalizado','ausente'=>'Ausente','cancelado'=>'Cancelado',
|
|
'en_servicio'=>'En servicio','en_espera_lugar'=>'Esp. lugar',
|
|
'en_recepcion'=>'Recepción','espera'=>'Espera',
|
|
];
|
|
|
|
echo '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">';
|
|
echo '<head><meta charset="UTF-8">
|
|
<style>
|
|
th { background:#1565c0; color:#fff; font-weight:bold; }
|
|
td,th { border:1px solid #ccc; padding:4px 8px; font-size:11px; }
|
|
.f { color:green; font-weight:bold; }
|
|
.a { color:red; }
|
|
</style></head><body>';
|
|
echo "<h2>Informe Turnero - {$fecha}</h2>";
|
|
echo '<table>';
|
|
echo '<tr>
|
|
<th>Código</th><th>Prioridad</th><th>Estado</th>
|
|
<th>Paciente</th><th>Tipo Doc</th><th>Documento</th><th>Celular</th>
|
|
<th>Lugar</th><th>Recepcionista</th><th>Bacteriólogo</th>
|
|
<th>Exámenes</th><th>Método Pago</th><th>Cobrado</th>
|
|
<th>Espera (min)</th><th>Servicio (min)</th><th>Total (min)</th>
|
|
<th>Hora entrada</th>
|
|
</tr>';
|
|
|
|
foreach ($turnos as $t) {
|
|
$cls = $t['estado'] === 'finalizado' ? ' class="f"' : ($t['estado'] === 'ausente' ? ' class="a"' : '');
|
|
$hora = $t['creado_at'] ? date('H:i', strtotime($t['creado_at'])) : '';
|
|
$cobrado = $t['cobrado'] ? number_format((float)$t['cobrado'], 0, ',', '.') : '';
|
|
$estadoLbl = $estados[$t['estado']] ?? $t['estado'];
|
|
echo "<tr{$cls}>
|
|
<td>{$t['codigo']}</td>
|
|
<td>{$t['prioridad']}</td>
|
|
<td>{$estadoLbl}</td>
|
|
<td>" . htmlspecialchars($t['paciente'] ?? '', ENT_QUOTES) . "</td>
|
|
<td>{$t['tipo_doc']}</td>
|
|
<td>{$t['num_doc']}</td>
|
|
<td>{$t['celular']}</td>
|
|
<td>" . htmlspecialchars($t['lugar'] ?? '', ENT_QUOTES) . "</td>
|
|
<td>" . htmlspecialchars($t['recepcionista'] ?? '', ENT_QUOTES) . "</td>
|
|
<td>" . htmlspecialchars($t['bacteriologo'] ?? '', ENT_QUOTES) . "</td>
|
|
<td>" . htmlspecialchars($t['examenes'] ?? '', ENT_QUOTES) . "</td>
|
|
<td>{$t['metodo_pago']}</td>
|
|
<td>{$cobrado}</td>
|
|
<td>{$t['espera_min']}</td>
|
|
<td>{$t['servicio_min']}</td>
|
|
<td>{$t['total_min']}</td>
|
|
<td>{$hora}</td>
|
|
</tr>\n";
|
|
}
|
|
echo '</table></body></html>';
|