fetchAll( "SELECT e.id AS enfermera_id, e.nombre_completo AS enfermera, YEAR(d.fecha_programada) AS anio, MONTH(d.fecha_programada) AS mes, COUNT(*) AS total, SUM(d.estado = 'completado') AS completados, SUM(d.estado = 'cancelado') AS cancelados, SUM(d.estado NOT IN ('completado','cancelado')) AS en_proceso FROM lab_domicilios d JOIN lab_asignaciones a ON a.domicilio_id = d.id AND a.estado NOT IN ('liberada') JOIN lab_enfermeras e ON e.id = a.enfermera_id $where GROUP BY e.id, YEAR(d.fecha_programada), MONTH(d.fecha_programada) ORDER BY e.nombre_completo, YEAR(d.fecha_programada) DESC, MONTH(d.fecha_programada) DESC", $params ); $meses_es = [ 1=>'Ene',2=>'Feb',3=>'Mar',4=>'Abr',5=>'May',6=>'Jun', 7=>'Jul',8=>'Ago',9=>'Sep',10=>'Oct',11=>'Nov',12=>'Dic', ]; foreach ($filas as &$f) { $t = (int)$f['total']; $f['tasa_pct'] = $t ? round((int)$f['completados'] / $t * 100) : 0; $f['mes_nombre'] = $meses_es[(int)$f['mes']] ?? $f['mes']; } unset($f); // Lista de enfermeras para el selector del filtro $enfermeras = $db->fetchAll( "SELECT id, nombre_completo FROM lab_enfermeras WHERE is_active = 1 ORDER BY nombre_completo" ); echo json_encode([ 'success' => true, 'filas' => $filas, 'enfermeras' => $enfermeras, ], JSON_UNESCAPED_UNICODE);