Reportes y Métricas
= htmlspecialchars($adminNombre) ?>Domicilios por enfermero
Domicilios por día
Estado de domicilios
Tiempo de traslado del enfermero
lab_actividad_admin)
fetchAll(
"SELECT o.id, p.nombre_completo AS paciente, p.numero_documento, p.eps,
o.estado, o.medico_nombre, o.fecha_orden, o.examenes_solicitados,
o.requiere_ayuno, o.horas_ayuno, o.created_at,
ar.full_name AS revisada_por, aa.full_name AS autorizada_por
FROM lab_ordenes_medicas o
JOIN lab_pacientes p ON p.id = o.paciente_id
LEFT JOIN admin_users ar ON ar.id = o.revisada_por
LEFT JOIN admin_users aa ON aa.id = o.autorizada_por
WHERE DATE(o.created_at) BETWEEN ? AND ?
ORDER BY o.created_at DESC",
[$desde, $hasta]
);
$filename = "ordenes_$desde\_$hasta.xls";
$headers = ['ID','Paciente','Documento','EPS','Estado','Médico','Fecha Orden','Exámenes','Ayuno','H.Ayuno','Creada','Revisada por','Autorizada por'];
break;
case 'domicilios':
// Soporta filtros extra enviados desde lab_domicilios.php
$sqlWhere = 'DATE(d.fecha_programada) BETWEEN ? AND ?';
$sqlParams = [$desde, $hasta];
// Si viene fecha única (filtro de día), tiene prioridad sobre desde/hasta
if (!empty($_GET['fecha'])) {
$sqlWhere = 'd.fecha_programada = ?';
$sqlParams = [$_GET['fecha']];
}
if (!empty($_GET['estado'])) {
$sqlWhere .= ' AND d.estado = ?';
$sqlParams[] = $_GET['estado'];
}
if (!empty($_GET['enfermera_id'])) {
$sqlWhere .= ' AND a.enfermera_id = ?';
$sqlParams[] = (int)$_GET['enfermera_id'];
}
$rows = $db->fetchAll(
"SELECT d.id,
p.nombre_completo AS paciente,
p.numero_documento,
p.telefono AS tel_paciente,
p.eps,
d.fecha_programada,
d.hora_programada,
d.hora_llegada,
d.hora_salida,
CASE
WHEN d.hora_llegada IS NOT NULL AND d.hora_salida IS NOT NULL
THEN CONCAT(TIMESTAMPDIFF(MINUTE, d.hora_llegada, d.hora_salida), ' min')
ELSE ''
END AS duracion_domicilio,
d.estado,
COALESCE(e.nombre_completo,'Sin asignar') AS enfermera,
d.tipo_servicio,
d.tipo_cliente,
COALESCE(d.seguro_nombre,'') AS seguro,
d.autorizacion,
d.examenes_solicitados,
d.direccion,
d.barrio,
d.ciudad,
COALESCE(d.valor_domicilio,0) AS valor_domicilio,
COALESCE(d.valor_copago,0) AS valor_copago,
COALESCE(d.copago_laboratorio,0) AS copago_laboratorio,
d.pago_estado,
d.pago_modo,
COALESCE(d.pago_monto,0) AS monto_recibido,
d.observaciones,
d.created_at,
COALESCE(nc.antecedentes,'') AS antecedentes,
COALESCE(nc.medicamentos,'') AS medicamentos,
COALESCE(nc.acudiente_nombre,'') AS acudiente_nombre,
COALESCE(nc.acudiente_documento,'') AS acudiente_documento,
COALESCE(
(SELECT GROUP_CONCAT(CONCAT(COALESCE(nl.titulo,''), ': ', COALESCE(nl.cuerpo,''))
ORDER BY nl.created_at ASC SEPARATOR ' | ')
FROM lab_domicilio_notas nl
WHERE nl.domicilio_id = d.id AND nl.tipo = 'libre'),
'') AS notas_libres
FROM lab_domicilios d
JOIN lab_pacientes p ON p.id = d.paciente_id
LEFT JOIN lab_asignaciones a ON a.domicilio_id = d.id AND a.estado NOT IN ('liberada')
LEFT JOIN lab_enfermeras e ON e.id = a.enfermera_id
LEFT JOIN lab_domicilio_notas nc ON nc.domicilio_id = d.id AND nc.tipo = 'clinica'
WHERE $sqlWhere
ORDER BY d.fecha_programada ASC, d.hora_programada ASC",
$sqlParams
);
$rangoLabel = !empty($_GET['fecha']) ? $_GET['fecha'] : "{$desde}_{$hasta}";
$filename = "domicilios_{$rangoLabel}.xls";
$headers = [
'ID','Paciente','Documento','Teléfono','EPS',
'Fecha','Hora programada','Hora llegada','Hora salida','Duración',
'Estado','Enfermera','Tipo servicio','Tipo cliente','Seguro','Autorización',
'Exámenes','Dirección','Barrio','Ciudad',
'Valor domicilio','Valor copago','Copago lab',
'Pago estado','Pago modo','Monto recibido',
'Observaciones','Registrado',
'Antecedentes','Medicamentos','Acudiente nombre','Acudiente documento','Notas libres',
];
break;
case 'pacientes':
$rows = $db->fetchAll(
"SELECT p.id, p.nombre_completo, p.tipo_documento, p.numero_documento,
p.telefono, p.email, p.eps, p.ciudad, p.barrio, p.is_active,
COUNT(o.id) AS total_ordenes, p.created_at
FROM lab_pacientes p
LEFT JOIN lab_ordenes_medicas o ON o.paciente_id = p.id
GROUP BY p.id
ORDER BY p.nombre_completo",
[]
);
$filename = "pacientes_" . date('Y-m-d') . ".xls";
$headers = ['ID','Nombre','Tipo Doc.','Documento','Teléfono','Email','EPS','Ciudad','Barrio','Activo','Total Órdenes','Registrado'];
break;
case 'pagos':
$pModo = in_array($_GET['modo'] ?? '', ['dia','mes','rango']) ? $_GET['modo'] : 'dia';
$pWheres = [];
$pParams = [];
switch ($pModo) {
case 'mes':
$pAnio = isset($_GET['anio']) && ctype_digit($_GET['anio']) ? (int)$_GET['anio'] : (int)date('Y');
$pMes = isset($_GET['mes']) && ctype_digit($_GET['mes']) ? (int)$_GET['mes'] : (int)date('n');
if ($pMes < 1 || $pMes > 12) $pMes = (int)date('n');
$pWheres[] = 'YEAR(d.fecha_programada) = ?'; $pParams[] = $pAnio;
$pWheres[] = 'MONTH(d.fecha_programada) = ?'; $pParams[] = $pMes;
$rangoNombre = sprintf('%04d-%02d', $pAnio, $pMes);
break;
case 'rango':
$pDesde = $_GET['desde'] ?? date('Y-m-01');
$pHasta = $_GET['hasta'] ?? date('Y-m-d');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pDesde)) $pDesde = date('Y-m-01');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pHasta)) $pHasta = date('Y-m-d');
$pWheres[] = 'DATE(d.fecha_programada) BETWEEN ? AND ?';
$pParams[] = $pDesde; $pParams[] = $pHasta;
$rangoNombre = "{$pDesde}_{$pHasta}";
break;
default: // dia
$pFecha = $_GET['fecha'] ?? date('Y-m-d');
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pFecha)) $pFecha = date('Y-m-d');
$pWheres[] = 'DATE(d.fecha_programada) = ?';
$pParams[] = $pFecha;
$rangoNombre = $pFecha;
}
if (!empty($_GET['enfermera_id']) && ctype_digit($_GET['enfermera_id'])) {
$pWheres[] = 'a.enfermera_id = ?';
$pParams[] = (int)$_GET['enfermera_id'];
}
$pWhere = $pWheres ? 'WHERE ' . implode(' AND ', $pWheres) : '';
$rows = $db->fetchAll(
"SELECT d.id, d.fecha_programada, d.pago_fecha,
p.nombre_completo AS paciente, p.numero_documento,
COALESCE(e.nombre_completo,'Sin asignar') AS enfermera,
d.tipo_cliente, COALESCE(d.seguro_nombre,'') AS seguro,
d.estado AS dom_estado,
COALESCE(d.valor_domicilio,0) AS valor_domicilio,
COALESCE(d.valor_copago,0) AS valor_copago,
COALESCE(d.pago_estado,'pendiente') AS pago_estado,
COALESCE(d.pago_modo,'') AS pago_modo,
COALESCE(d.pago_monto,0) AS pago_monto,
COALESCE(d.pago_notas,'') AS pago_notas
FROM lab_domicilios d
JOIN lab_pacientes p ON p.id = d.paciente_id
LEFT JOIN lab_asignaciones a ON a.domicilio_id = d.id AND a.estado NOT IN ('liberada')
LEFT JOIN lab_enfermeras e ON e.id = a.enfermera_id
$pWhere
ORDER BY d.fecha_programada ASC, d.id ASC",
$pParams
);
$filename = "reporte_pagos_{$rangoNombre}.xls";
$headers = [
'ID','Fecha programada','Fecha pago','Paciente','Documento',
'Enfermero/a','Tipo cliente','Seguro','Estado domicilio',
'Valor domicilio','Valor copago','Estado pago','Modo pago','Monto recibido','Notas pago',
];
break;
default:
http_response_code(400);
exit('Tipo de exportación no válido');
}
header('Content-Type: application/vnd.ms-excel; charset=utf-8');
header("Content-Disposition: attachment; filename=\"$filename\"");
header('Pragma: no-cache');
$esc = fn($v) => htmlspecialchars((string)$v, ENT_XML1, 'UTF-8');
echo '<' . '?xml version="1.0" encoding="UTF-8"?' . '>' . "\n";
echo '<' . '?mso-application progid="Excel.Sheet"?' . '>' . "\n";
echo '' . "\n";
echo '
lab_actividad_admin)