import React, { useState, useCallback } from 'react'; import { Box, Typography, Paper, CircularProgress, Alert, Button, TableContainer, Table, TableHead, TableRow, TableCell, TableBody } from '@mui/material'; import reportesService from '../../services/Reportes/reportesService'; import type { TiradasPublicacionesSeccionesDto } from '../../models/dtos/Reportes/TiradasPublicacionesSeccionesDto'; import SeleccionaReporteTiradasPublicacionesSecciones from './SeleccionaReporteTiradasPublicacionesSecciones'; import * as XLSX from 'xlsx'; import axios from 'axios'; const ReporteTiradasPublicacionesSeccionesPage: React.FC = () => { const [reportData, setReportData] = useState([]); const [loading, setLoading] = useState(false); const [loadingPdf, setLoadingPdf] = useState(false); const [error, setError] = useState(null); const [apiErrorParams, setApiErrorParams] = useState(null); const [showParamSelector, setShowParamSelector] = useState(true); const [currentParams, setCurrentParams] = useState<{ idPublicacion: number; fechaDesde: string; fechaHasta: string; idPlanta?: number | null; consolidado: boolean; nombrePublicacion?: string; nombrePlanta?: string; mesAnioParaNombreArchivo?: string; } | null>(null); const handleGenerarReporte = useCallback(async (params: { idPublicacion: number; fechaDesde: string; fechaHasta: string; idPlanta?: number | null; consolidado: boolean; }) => { setLoading(true); setError(null); setApiErrorParams(null); setReportData([]); const pubService = (await import('../../services/Distribucion/publicacionService')).default; const pubData = await pubService.getPublicacionById(params.idPublicacion); let plantaNombre = "Consolidado"; if (!params.consolidado && params.idPlanta) { const plantaService = (await import('../../services/Impresion/plantaService')).default; const plantaData = await plantaService.getPlantaById(params.idPlanta); plantaNombre = plantaData?.nombre ?? "N/A"; } const mesAnioParts = params.fechaDesde.split('-'); const mesAnioNombre = `${mesAnioParts[1]}/${mesAnioParts[0]}`; setCurrentParams({...params, nombrePublicacion: pubData?.nombre, nombrePlanta: plantaNombre, mesAnioParaNombreArchivo: mesAnioNombre}); try { const data = await reportesService.getTiradasPublicacionesSecciones(params); setReportData(data); if (data.length === 0) { setError("No se encontraron datos para los parámetros seleccionados."); } setShowParamSelector(false); } catch (err: any) { const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Ocurrió un error al generar el reporte.'; setApiErrorParams(message); } finally { setLoading(false); } }, []); const handleVolverAParametros = useCallback(() => { setShowParamSelector(true); setReportData([]); setError(null); setApiErrorParams(null); setCurrentParams(null); }, []); const handleExportToExcel = useCallback(() => { if (reportData.length === 0) { alert("No hay datos para exportar."); return; } const dataToExport = reportData.map(item => ({ "Nombre Sección": item.nombreSeccion, "Total Páginas Impresas": item.totalPaginasImpresas, "Cantidad Ediciones": item.cantidadTiradas, "Total Páginas x Edición": item.totalPaginasEjemplares, "Total Ejemplares": item.totalEjemplares, "Prom. Pág./Ejemplar": item.promedioPaginasPorEjemplar, })); const ws = XLSX.utils.json_to_sheet(dataToExport); const headers = Object.keys(dataToExport[0] || {}); ws['!cols'] = headers.map(h => { const maxLen = Math.max(...dataToExport.map(row => (row as any)[h]?.toString().length ?? 0), h.length); return { wch: maxLen + 2 }; }); ws['!freeze'] = { xSplit: 0, ySplit: 1 }; const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "TiradasSecciones"); let fileName = "ReporteTiradasSecciones"; if (currentParams) { fileName += `_${currentParams.nombrePublicacion?.replace(/\s+/g, '') ?? `Pub${currentParams.idPublicacion}`}`; if (!currentParams.consolidado) fileName += `_Planta${currentParams.idPlanta}`; else fileName += "_Consolidado"; fileName += `_${currentParams.mesAnioParaNombreArchivo?.replace('/', '-')}`; } fileName += ".xlsx"; XLSX.writeFile(wb, fileName); }, [reportData, currentParams]); const handleGenerarYAbrirPdf = useCallback(async () => { if (!currentParams) { setError("Primero debe generar el reporte en pantalla o seleccionar parámetros."); return; } setLoadingPdf(true); setError(null); try { const blob = await reportesService.getTiradasPublicacionesSeccionesPdf(currentParams); if (blob.type === "application/json") { const text = await blob.text(); const msg = JSON.parse(text).message ?? "Error inesperado al generar PDF."; setError(msg); } else { const url = URL.createObjectURL(blob); const w = window.open(url, '_blank'); if (!w) alert("Permite popups para ver el PDF."); } } catch { setError('Ocurrió un error al generar el PDF.'); } finally { setLoadingPdf(false); } }, [currentParams]); if (showParamSelector) { return ( ); } return ( Reporte: Tiradas por Publicación y Secciones {loading && } {error && !loading && {error}} {!loading && !error && reportData.length > 0 && ( Nombre Sección Total Páginas Imp. Cant. Ediciones Total Pág. x Edición Total Ejemplares Prom. Pág./Ejemplar {reportData.map((row, idx) => ( {row.nombreSeccion} {row.totalPaginasImpresas.toLocaleString('es-AR')} {row.cantidadTiradas.toLocaleString('es-AR')} {row.totalPaginasEjemplares.toLocaleString('es-AR')} {row.totalEjemplares.toLocaleString('es-AR')} {row.promedioPaginasPorEjemplar.toLocaleString('es-AR')} ))}
)} {!loading && !error && reportData.length === 0 && (No se encontraron datos para los criterios seleccionados.)}
); }; export default ReporteTiradasPublicacionesSeccionesPage;