Files
whatsapp/api/kpi_actividad.php
T
2026-05-11 12:21:56 -05:00

132 lines
5.1 KiB
PHP

<?php
/**
* GET /api/kpi_actividad.php
*
* Devuelve métricas de actividad de pacientes por rango de fechas:
* - Por día: usuarios únicos que escriben y agendamientos creados.
* - Por día de la semana: agregado del rango seleccionado.
*
* Parámetros GET:
* desde (YYYY-MM-DD) — fecha inicio, default hoy-29 días
* hasta (YYYY-MM-DD) — fecha fin, default hoy
*/
require_once __DIR__ . '/../config/config.php';
error_reporting(E_ERROR | E_PARSE);
ini_set('display_errors', '0');
requireAuthentication();
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
try {
$db = Database::getInstance();
// ── Rango de fechas ──────────────────────────────────────
$hoy = date('Y-m-d');
$desde = $_GET['desde'] ?? date('Y-m-d', strtotime('-29 days'));
$hasta = $_GET['hasta'] ?? $hoy;
// Sanitizar: solo fechas válidas
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $desde)) $desde = date('Y-m-d', strtotime('-29 days'));
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $hasta)) $hasta = $hoy;
// No permitir rangos invertidos
if ($desde > $hasta) [$desde, $hasta] = [$hasta, $desde];
// ── Mensajes entrantes por día (usuarios únicos) ─────────
$msgRows = $db->fetchAll("
SELECT
DATE(created_at) AS fecha,
COUNT(DISTINCT user_id) AS usuarios,
COUNT(*) AS total_mensajes
FROM conversations
WHERE direction = 'incoming'
AND DATE(created_at) BETWEEN ? AND ?
GROUP BY DATE(created_at)
ORDER BY fecha ASC
", [$desde, $hasta]);
// ── Agendamientos (turnos creados) por día ───────────────
$turnosRows = $db->fetchAll("
SELECT
DATE(creado_at) AS fecha,
COUNT(*) AS agendamientos
FROM turnero_turnos
WHERE DATE(creado_at) BETWEEN ? AND ?
GROUP BY DATE(creado_at)
ORDER BY fecha ASC
", [$desde, $hasta]);
// ── Construir mapa fecha → datos combinados ──────────────
$dias = [];
// Generar todos los días del rango para que no haya huecos
$cur = new DateTime($desde);
$fin = new DateTime($hasta);
while ($cur <= $fin) {
$f = $cur->format('Y-m-d');
$dias[$f] = ['fecha' => $f, 'usuarios' => 0, 'total_mensajes' => 0, 'agendamientos' => 0];
$cur->modify('+1 day');
}
foreach ($msgRows as $r) {
if (isset($dias[$r['fecha']])) {
$dias[$r['fecha']]['usuarios'] = (int)$r['usuarios'];
$dias[$r['fecha']]['total_mensajes'] = (int)$r['total_mensajes'];
}
}
foreach ($turnosRows as $r) {
if (isset($dias[$r['fecha']])) {
$dias[$r['fecha']]['agendamientos'] = (int)$r['agendamientos'];
}
}
$porDia = array_values($dias);
// ── Agrupado por día de la semana (0=Domingo … 6=Sábado) ─
$semana = [
0 => ['dia' => 'Domingo', 'usuarios' => 0, 'agendamientos' => 0],
1 => ['dia' => 'Lunes', 'usuarios' => 0, 'agendamientos' => 0],
2 => ['dia' => 'Martes', 'usuarios' => 0, 'agendamientos' => 0],
3 => ['dia' => 'Miércoles', 'usuarios' => 0, 'agendamientos' => 0],
4 => ['dia' => 'Jueves', 'usuarios' => 0, 'agendamientos' => 0],
5 => ['dia' => 'Viernes', 'usuarios' => 0, 'agendamientos' => 0],
6 => ['dia' => 'Sábado', 'usuarios' => 0, 'agendamientos' => 0],
];
foreach ($porDia as $d) {
$dow = (int)(new DateTime($d['fecha']))->format('w'); // 0=Dom
$semana[$dow]['usuarios'] += $d['usuarios'];
$semana[$dow]['agendamientos'] += $d['agendamientos'];
}
// ── Totales del rango ────────────────────────────────────
$totalUsuarios = array_sum(array_column($porDia, 'usuarios'));
$totalMensajes = array_sum(array_column($porDia, 'total_mensajes'));
$totalAgendamientos = array_sum(array_column($porDia, 'agendamientos'));
// Día de semana pico (más usuarios)
$picoDow = array_keys($semana, max($semana, fn($a,$b) => $a['usuarios'] <=> $b['usuarios']))[0] ?? null;
$picoDow = array_reduce(array_keys($semana), fn($carry, $k) => ($semana[$k]['usuarios'] > $semana[$carry]['usuarios'] ? $k : $carry), 0);
echo json_encode([
'ok' => true,
'desde' => $desde,
'hasta' => $hasta,
'totales' => [
'usuarios' => $totalUsuarios,
'mensajes' => $totalMensajes,
'agendamientos' => $totalAgendamientos,
'pico_semana' => $semana[$picoDow]['dia'] ?? '—',
],
'por_dia' => $porDia,
'por_dia_semana' => array_values($semana),
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['ok' => false, 'error' => $e->getMessage()]);
}