Juan Felipe Zapata Moreno 7986cc3650 Cambio exportación Excel
2025-10-07 13:21:00 -06:00

238 lines
7.5 KiB
PHP

<?php
namespace App\Http\Controllers\Dashboard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class AtencionController extends BaseController
{
public function Atencion(Request $request)
{
$query = $request->only(['start', 'end', 'type', 'action', 'period', 'charts_only']);
$input = array_merge(['action' => 'index', 'type' => 'api'], $query);
$startDate = $input['start'] ?? date('Y-01-01');
$endDate = $input['end'] ?? date('Y-12-31');
$period = $input['period'] ?? null;
$chartsOnly = $input['charts_only'] ?? false;
// Cache key para diferentes tipos de peticiones
$cacheKey = 'atencion_' . md5(serialize([
'start' => $startDate,
'end' => $endDate,
'period' => $period,
'charts_only' => $chartsOnly
]));
// Intentar obtener desde cache (2 minutos)
if (Cache::has($cacheKey)) {
return response()->json(Cache::get($cacheKey), 200)
->header('Content-Type', 'application/json');
}
try {
// Si solo necesitamos gráficas, hacer menos peticiones
if ($chartsOnly) {
$result = $this->getChartsData($startDate, $endDate);
} else {
$result = $this->getFullData($startDate, $endDate, $period);
}
// Cachear resultado por 2 minutos
Cache::put($cacheKey, $result, 120);
return response()->json($result, 200)
->header('Content-Type', 'application/json');
} catch (\Exception $e) {
Log::error('Error en la consulta de atención', ['exception' => $e->getMessage()]);
return response()->json(['error' => 'Error en la consulta de atención'], 500);
}
}
private function getChartsData($startDate, $endDate)
{
$baseParams = [
'start_date' => $startDate,
'end_date' => $endDate,
'type' => 'api',
'action' => 'index',
];
$baseUrl = 'https://apoyos.comalcalco.gob.mx/beneficiaries/stats-by-date-range';
// Solo hacer la petición principal para gráficas
$response = Http::timeout(15)->get($baseUrl, $baseParams);
if (!$response->successful()) {
throw new \Exception('Error del servicio principal');
}
return $response->json();
}
private function getFullData($startDate, $endDate, $period)
{
$baseParams = [
'start_date' => $startDate,
'end_date' => $endDate,
'type' => 'api',
'action' => 'index',
];
$urls = [
'main' => 'https://apoyos.comalcalco.gob.mx/beneficiaries/stats-by-date-range',
'counts' => 'https://apoyos.comalcalco.gob.mx/beneficiaries/counts-by-date',
'dashboard' => 'https://apoyos.comalcalco.gob.mx/beneficiaries/dashboard/api',
'dashboard_servicio' => 'https://apoyos.comalcalco.gob.mx/beneficiaries/dashboard/api?type=servicio'
];
// Hacer peticiones en paralelo usando HTTP Pool
$responses = Http::pool(fn($pool) => [
$pool->timeout(15)->get($urls['main'], $baseParams),
$pool->timeout(15)->get($urls['counts'], [
'start_date' => $startDate,
'end_date' => $endDate,
]),
$pool->timeout(15)->get($urls['dashboard']),
$pool->timeout(15)->get($urls['dashboard_servicio'])
]);
$mainData = [];
$countsAc = [];
$dashboardData = [];
$dashboardServicioData = [];
// Procesar respuestas
if ($responses[0]->successful()) {
$mainData = $responses[0]->json();
} else {
Log::error('Error en petición principal', ['status' => $responses[0]->status()]);
}
if ($responses[1]->successful()) {
$countsAc = $responses[1]->json();
} else {
Log::error('Error en petición counts', ['status' => $responses[1]->status()]);
}
if ($responses[2]->successful()) {
$dashboardData = $responses[2]->json();
} else {
Log::error('Error en petición dashboard', ['status' => $responses[2]->status()]);
}
if ($responses[3]->successful()) {
$dashboardServicioData = $responses[3]->json();
} else {
Log::error('Error en petición dashboard servicio', ['status' => $responses[3]->status()]);
}
// Combinar todos los resultados
return array_merge(
is_array($mainData) ? $mainData : [],
[
'counts' => $countsAc,
'dashboard' => $dashboardData,
'dashboard_servicio' => $dashboardServicioData,
]
);
}
public function exportExcel(Request $request)
{
try {
// Obtener parámetros necesarios para la API
$params = $request->only([
'start_date',
'end_date',
'department'
]);
// Validaciones básicas
if (!isset($params['start_date']) || !isset($params['end_date'])) {
return response()->json([
'error' => 'Las fechas son requeridas'
], 400);
}
if (!isset($params['department']) || $params['department'] === '') {
return response()->json([
'error' => 'El departamento es requerido'
], 400);
}
// Validar que department sea 1 o 3
if (!in_array((int)$params['department'], [1, 3])) {
return response()->json([
'error' => 'El departamento debe ser Atención Ciudadana o DIF'
], 400);
}
$url = 'https://apoyos.comalcalco.gob.mx/api/beneficiaries/export-excel';
// Hacer la petición a la API externa
$response = Http::withoutVerifying()
->timeout(60)
->get($url, $params);
if (!$response->successful()) {
Log::error('Error al exportar Excel', [
'status' => $response->status(),
'body' => $response->body(),
'params' => $params
]);
return response()->json([
'error' => 'Error al generar el archivo Excel: ' . $response->body()
], $response->status());
}
// Verificar que la respuesta sea realmente un Excel
$contentType = $response->header('Content-Type');
if (!str_contains($contentType, 'spreadsheet') && !str_contains($contentType, 'excel') && !str_contains($contentType, 'octet-stream')) {
Log::error('Respuesta no es un archivo Excel', [
'url' => $url,
'params' => $params,
'status' => $response->status(),
'content_type' => $contentType,
'body_preview' => substr($response->body(), 0, 500)
]);
return response()->json([
'error' => 'La API externa no devolvió un archivo Excel válido. URL: ' . $url . ' | Status: ' . $response->status()
], 400);
}
// Nombre del departamento para el archivo
$departmentName = $params['department'] == 1 ? 'AtencionCiudadana' : 'DIF';
// Retornar el archivo Excel directamente con headers correctos
return response($response->body(), 200, [
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Content-Disposition' => 'attachment; filename="beneficiarios_' . $departmentName . '_' .
$params['start_date'] . '_' . $params['end_date'] . '.xlsx"',
'Content-Length' => strlen($response->body()),
'Cache-Control' => 'no-cache, no-store, must-revalidate',
'Pragma' => 'no-cache',
'Expires' => '0'
]);
} catch (\Exception $e) {
Log::error('Error en exportExcel', [
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
'params' => $request->all()
]);
return response()->json([
'error' => 'Error interno del servidor: ' . $e->getMessage()
], 500);
}
}
}