1ra Versión
This commit is contained in:
+585
@@ -0,0 +1,585 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tipoReporte = document.getElementById('tipo-reporte');
|
||||
const parametros = document.getElementById('parametros');
|
||||
const generarBtn = document.getElementById('generar-reporte');
|
||||
const exportarBtn = document.getElementById('exportar-pdf');
|
||||
const reporteContainer = document.getElementById('reporte-container');
|
||||
const reporteContenido = document.getElementById('reporte-contenido');
|
||||
const spinner = document.getElementById('spinner');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
|
||||
// Variable global para almacenar el período actual
|
||||
let periodoActual = {
|
||||
tipo: 'diario',
|
||||
fecha: new Date().toISOString().split('T')[0],
|
||||
nombreArchivo: 'reporte'
|
||||
};
|
||||
|
||||
// ========== FUNCIONES AUXILIARES ==========
|
||||
|
||||
function formatoMoneda(valor) {
|
||||
return new Intl.NumberFormat('es-AR', {
|
||||
style: 'currency',
|
||||
currency: 'ARS'
|
||||
}).format(valor);
|
||||
}
|
||||
|
||||
function obtenerSemanaActual() {
|
||||
const hoy = new Date();
|
||||
const diaSemana = hoy.getDay();
|
||||
const lunes = new Date(hoy);
|
||||
const diferenciaDias = diaSemana === 0 ? -6 : 1 - diaSemana;
|
||||
lunes.setDate(hoy.getDate() + diferenciaDias);
|
||||
|
||||
const fechaReferencia = new Date(lunes.getFullYear(), 0, 4);
|
||||
const diaSemanaRef = fechaReferencia.getDay();
|
||||
const lunesRef = new Date(fechaReferencia);
|
||||
lunesRef.setDate(fechaReferencia.getDate() - (diaSemanaRef === 0 ? 6 : diaSemanaRef - 1));
|
||||
|
||||
const diffMs = lunes - lunesRef;
|
||||
const diffDias = Math.floor(diffMs / (24 * 60 * 60 * 1000));
|
||||
const numeroSemana = Math.floor(diffDias / 7) + 1;
|
||||
const ano = lunes.getFullYear();
|
||||
|
||||
return `${ano}-W${String(numeroSemana).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
function mostrarSpinner() {
|
||||
spinner.style.display = 'flex';
|
||||
}
|
||||
|
||||
function ocultarSpinner() {
|
||||
spinner.style.display = 'none';
|
||||
}
|
||||
|
||||
function mostrarError(mensaje) {
|
||||
errorMessage.textContent = mensaje;
|
||||
errorMessage.style.display = 'block';
|
||||
}
|
||||
|
||||
function ocultarError() {
|
||||
errorMessage.style.display = 'none';
|
||||
}
|
||||
|
||||
function generarNombresYMetadatos(tipo, data) {
|
||||
let nombreArchivo = 'reporte';
|
||||
|
||||
if (tipo === 'diario') {
|
||||
const fecha = new Date(data.periodo + 'T00:00:00');
|
||||
const fechaCorta = fecha.getDate().toString().padStart(2, '0') + '-' +
|
||||
(fecha.getMonth() + 1).toString().padStart(2, '0') + '-' +
|
||||
fecha.getFullYear().toString().slice(-2);
|
||||
nombreArchivo = 'reporte_' + fechaCorta;
|
||||
} else if (tipo === 'semanal') {
|
||||
const inicio = new Date(data.fecha_inicio + 'T00:00:00');
|
||||
const fin = new Date(data.fecha_fin + 'T00:00:00');
|
||||
const diaInicio = inicio.getDate().toString().padStart(2, '0');
|
||||
const diaFin = fin.getDate().toString().padStart(2, '0');
|
||||
const mesNombre = inicio.toLocaleDateString('es-ES', { month: 'long' });
|
||||
nombreArchivo = `reporte_semana_${diaInicio}-${diaFin}_${mesNombre}`;
|
||||
} else if (tipo === 'mensual') {
|
||||
const mesesNombres = ['', 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];
|
||||
let nombreMes = 'mensual';
|
||||
let anio = new Date().getFullYear();
|
||||
if (data.nombre_mes) {
|
||||
nombreMes = data.nombre_mes;
|
||||
anio = data.nombre_anio || anio;
|
||||
} else if (data.fecha_inicio) {
|
||||
const f = new Date(data.fecha_inicio + 'T00:00:00');
|
||||
if (!isNaN(f.getTime())) {
|
||||
nombreMes = f.toLocaleDateString('es-ES', { month: 'long' });
|
||||
anio = f.getFullYear();
|
||||
}
|
||||
} else if (data.periodo && /^\d{4}-\d{2}$/.test(String(data.periodo))) {
|
||||
const parts = String(data.periodo).split('-');
|
||||
nombreMes = mesesNombres[parseInt(parts[1] || '0')] || nombreMes;
|
||||
anio = parts[0] || anio;
|
||||
}
|
||||
nombreArchivo = 'reporte_' + nombreMes + '_' + anio;
|
||||
} else if (tipo === 'anual') {
|
||||
const anio = data.periodo || data.anio || (data.fecha_inicio ? (new Date(data.fecha_inicio + 'T00:00:00')).getFullYear() : new Date().getFullYear());
|
||||
nombreArchivo = 'reporte_' + anio;
|
||||
}
|
||||
|
||||
periodoActual.tipo = tipo;
|
||||
periodoActual.nombreArchivo = nombreArchivo;
|
||||
}
|
||||
|
||||
function renderizarDiario(data) {
|
||||
const fecha = new Date(data.periodo + 'T00:00:00');
|
||||
const opciones = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
|
||||
const fechaFormato = fecha.toLocaleDateString('es-ES', opciones);
|
||||
const fechaCorta = fecha.getDate().toString().padStart(2, '0') + '-' +
|
||||
(fecha.getMonth() + 1).toString().padStart(2, '0') + '-' +
|
||||
fecha.getFullYear().toString().slice(-2);
|
||||
|
||||
let html = `
|
||||
<div class="reporte-titulo">
|
||||
<h2>📅 Reporte Diario ${fechaCorta} - Cierre de Caja</h2>
|
||||
<div class="reporte-periodo">Reporte ${fechaFormato}</div>
|
||||
</div>
|
||||
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Hora</th>
|
||||
<th>Tipo de Operación</th>
|
||||
<th>Descripción / Detalle</th>
|
||||
<th style="text-align: right;">Monto ($)</th>
|
||||
<th>Usuario</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (data.transacciones && data.transacciones.length > 0) {
|
||||
data.transacciones.forEach(tx => {
|
||||
const monto = parseFloat(tx.monto);
|
||||
const claseNegativo = monto < 0 ? 'negativo' : '';
|
||||
html += `
|
||||
<tr>
|
||||
<td>${tx.hora || '--:--'}</td>
|
||||
<td><strong>${tx.tipo_operacion}</strong></td>
|
||||
<td>${tx.descripcion || '--'}</td>
|
||||
<td class="monto ${claseNegativo}">${formatoMoneda(monto)}</td>
|
||||
<td>${tx.usuario_registro || 'Sistema'}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
} else {
|
||||
html += `<tr><td colspan="5" style="text-align: center;">Sin transacciones registradas</td></tr>`;
|
||||
}
|
||||
|
||||
html += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="resumen-reporte">
|
||||
<h3>Resumen del Día</h3>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ingresos Reservas:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.resumen.ingresos_reservas)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ingresos Cantina:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.resumen.ingresos_cantina)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Total Ingresos:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.resumen.total_ingresos)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Egresos Totales:</span>
|
||||
<span class="resumen-valor negativo">-${formatoMoneda(data.resumen.egresos)}</span>
|
||||
</div>
|
||||
<hr style="border: none; border-top: 2px solid #2c3e50; margin: 15px 0;">
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">💰 SALDO NETO:</span>
|
||||
<span class="resumen-valor ${data.resumen.saldo_neto < 0 ? 'negativo' : ''}">${formatoMoneda(data.resumen.saldo_neto)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
reporteContenido.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderizarSemanal(data) {
|
||||
const inicio = new Date(data.fecha_inicio + 'T00:00:00');
|
||||
const fin = new Date(data.fecha_fin + 'T00:00:00');
|
||||
const opciones = { month: 'short', day: 'numeric' };
|
||||
const inicioCorta = inicio.getDate().toString().padStart(2, '0') + '-' +
|
||||
(inicio.getMonth() + 1).toString().padStart(2, '0');
|
||||
const finCorta = fin.getDate().toString().padStart(2, '0') + '-' +
|
||||
(fin.getMonth() + 1).toString().padStart(2, '0') + '-' +
|
||||
fin.getFullYear().toString().slice(-2);
|
||||
|
||||
let html = `
|
||||
<div class="reporte-titulo">
|
||||
<h2>📆 Reporte Semanal ${inicioCorta} al ${finCorta} - Flujo de Caja</h2>
|
||||
<div class="reporte-periodo">Reporte Semana del ${inicio.toLocaleDateString('es-ES', opciones)} al ${fin.toLocaleDateString('es-ES', opciones)}</div>
|
||||
</div>
|
||||
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Día de la Semana</th>
|
||||
<th style="text-align: right;">Ingresos Reservas ($)</th>
|
||||
<th style="text-align: right;">Ingresos Cantina ($)</th>
|
||||
<th style="text-align: right;">Costo Mercadería ($)</th>
|
||||
<th style="text-align: right;">Saldo Neto del Día ($)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (data.dias && data.dias.length > 0) {
|
||||
data.dias.forEach(dia => {
|
||||
const nombreDia = new Date(dia.dia + 'T00:00:00').toLocaleDateString('es-ES', { weekday: 'long' });
|
||||
const saldoNeto = dia.saldo_neto;
|
||||
const claseNegativo = saldoNeto < 0 ? 'negativo' : '';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td><strong>${nombreDia.charAt(0).toUpperCase() + nombreDia.slice(1)} (${dia.dia})</strong></td>
|
||||
<td class="monto">${formatoMoneda(dia.ingresos_reservas)}</td>
|
||||
<td class="monto">${formatoMoneda(dia.ingresos_cantina)}</td>
|
||||
<td class="monto negativo">${formatoMoneda(dia.costo_mercaderia)}</td>
|
||||
<td class="monto ${claseNegativo}"><strong>${formatoMoneda(saldoNeto)}</strong></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="5" style="background: #34495e; color: white; text-align: center;">Resumen de la Semana</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: right;"><strong>Ingresos Reservas Total:</strong></td>
|
||||
<td style="text-align: right;" colspan="4" class="monto encabezado">${formatoMoneda(data.resumen.ingresos_reservas_totales)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><strong>Ingresos Cantina Total:</strong></td>
|
||||
<td style="text-align: right;" colspan="4" class="monto encabezado">${formatoMoneda(data.resumen.ingresos_cantina_totales)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><strong>Costo Mercadería Total:</strong></td>
|
||||
<td style="text-align: right;" colspan="4" class="monto encabezado negativo">${formatoMoneda(data.resumen.costo_mercaderia_total)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right;"><strong>💰 Saldo Neto Semana:</strong></td>
|
||||
<td style="text-align: right;" colspan="4" class="monto encabezado ${data.resumen.saldo_neto_semana < 0 ? 'negativo' : ''}">${formatoMoneda(data.resumen.saldo_neto_semana)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="resumen-reporte">
|
||||
<h3>% Ocupación Promedio</h3>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Turnos Ocupados:</span>
|
||||
<span class="resumen-valor neutral">${data.resumen.turnos_ocupados} / ${data.resumen.turnos_disponibles}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Porcentaje Ocupación:</span>
|
||||
<span class="resumen-valor neutral">${data.resumen.ocupacion_promedio}%</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
reporteContenido.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderizarMensual(data) {
|
||||
const fechaInicio = new Date(data.fecha_inicio + 'T00:00:00');
|
||||
const mesCorta = (fechaInicio.getMonth() + 1).toString().padStart(2, '0') + '-' +
|
||||
fechaInicio.getFullYear().toString().slice(-2);
|
||||
const nombreMes = data.nombre_mes || fechaInicio.toLocaleDateString('es-ES', { month: 'long' });
|
||||
|
||||
let html = `
|
||||
<div class="reporte-titulo">
|
||||
<h2>📊 Reporte Mensual ${mesCorta} - Rentabilidad</h2>
|
||||
<div class="reporte-periodo">Reporte de ${nombreMes.charAt(0).toUpperCase() + nombreMes.slice(1)}</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin-top: 30px; color: #2c3e50;">Ingreso por Categoría</h3>
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Concepto / Categoría</th>
|
||||
<th style="text-align: right;">Operaciones</th>
|
||||
<th style="text-align: right;">Monto ($)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (data.categorias && data.categorias.length > 0) {
|
||||
data.categorias.forEach(cat => {
|
||||
html += `
|
||||
<tr>
|
||||
<td><strong>${cat.categoria}</strong></td>
|
||||
<td style="text-align: right;">${cat.operaciones}</td>
|
||||
<td class="monto">${formatoMoneda(cat.monto)}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3 style="margin-top: 30px; color: #2c3e50;">Gastos Fijos</h3>
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nombre del Gasto</th>
|
||||
<th style="text-align: right;">Monto Gasto ($)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (data.gastos_fijos && data.gastos_fijos.length > 0) {
|
||||
data.gastos_fijos.forEach(gasto => {
|
||||
html += `
|
||||
<tr>
|
||||
<td>${gasto.descripcion}</td>
|
||||
<td class="monto negativo">${formatoMoneda(gasto.monto)}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
} else {
|
||||
html += `
|
||||
<tr>
|
||||
<td colspan="2" style="text-align: center; color: #7f8c8d;">Sin gastos registrados</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
html += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="resumen-reporte" style="margin-top: 30px;">
|
||||
<h3>Estado de Resultados</h3>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ingresos Totales:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.resumen.ingresos_totales)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Costo de Mercadería:</span>
|
||||
<span class="resumen-valor negativo">-${formatoMoneda(data.resumen.costo_mercaderia)}</span>
|
||||
</div>
|
||||
<hr style="border: none; border-top: 1px solid #2c3e50; margin: 15px 0;">
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ganancia Bruta:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.resumen.ganancia_bruta)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Gastos Fijos:</span>
|
||||
<span class="resumen-valor negativo">-${formatoMoneda(data.resumen.gastos_fijos_total)}</span>
|
||||
</div>
|
||||
<hr style="border: none; border-top: 2px solid #2c3e50; margin: 15px 0;">
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">💰 GANANCIA NETA:</span>
|
||||
<span class="resumen-valor ${data.resumen.ganancia_neta < 0 ? 'negativo' : ''}" style="font-size: 1.3em;">${formatoMoneda(data.resumen.ganancia_neta)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
reporteContenido.innerHTML = html;
|
||||
}
|
||||
|
||||
function renderizarAnual(data) {
|
||||
let notaAnoActual = '';
|
||||
if (data.es_ano_actual) {
|
||||
notaAnoActual = `
|
||||
<div style="background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 12px; margin-bottom: 20px; color: #856404;">
|
||||
<strong>ℹ️ Nota:</strong> Este es el año en curso. El reporte muestra datos hasta el ${data.mes_actual}° mes (mes actual).
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<div class="reporte-titulo">
|
||||
<h2>📈 Reporte Anual ${data.periodo} - Visión Estratégica</h2>
|
||||
<div class="reporte-periodo">Reporte Año ${data.periodo}</div>
|
||||
</div>
|
||||
${notaAnoActual}
|
||||
|
||||
<table class="reporte-tabla">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Mes</th>
|
||||
<th style="text-align: right;">Ingreso Operativo ($)</th>
|
||||
<th style="text-align: right;">Costo Bruto ($)</th>
|
||||
<th style="text-align: right;">Costo Operativo ($)</th>
|
||||
<th style="text-align: right;">Ganancia Bruta ($)</th>
|
||||
<th style="text-align: right;">Ganancia Neta ($)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
`;
|
||||
|
||||
if (data.meses && data.meses.length > 0) {
|
||||
data.meses.forEach(mes => {
|
||||
const gananciaNeta = parseFloat(mes.ganancia_neta);
|
||||
const claseNegativo = gananciaNeta < 0 ? 'negativo' : '';
|
||||
|
||||
html += `
|
||||
<tr>
|
||||
<td><strong>${mes.mes}</strong></td>
|
||||
<td class="monto">${formatoMoneda(mes.ingreso_operativo)}</td>
|
||||
<td class="monto negativo">${formatoMoneda(mes.costo_bruto)}</td>
|
||||
<td class="monto negativo">${formatoMoneda(mes.costo_operativo)}</td>
|
||||
<td class="monto">${formatoMoneda(mes.ganancia_bruta)}</td>
|
||||
<td class="monto ${claseNegativo}"><strong>${formatoMoneda(gananciaNeta)}</strong></td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
}
|
||||
|
||||
html += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="resumen-reporte" style="margin-top: 30px;">
|
||||
<h3>Totales Anuales</h3>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ingreso Operativo Total:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.totales.ingreso_operativo_total)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Costo Bruto Total:</span>
|
||||
<span class="resumen-valor negativo">-${formatoMoneda(data.totales.costo_bruto_total)}</span>
|
||||
</div>
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Costo Operativo Total:</span>
|
||||
<span class="resumen-valor negativo">-${formatoMoneda(data.totales.costo_operativo_total)}</span>
|
||||
</div>
|
||||
<hr style="border: none; border-top: 1px solid #2c3e50; margin: 15px 0;">
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">Ganancia Bruta Total:</span>
|
||||
<span class="resumen-valor">${formatoMoneda(data.totales.ganancia_bruta_total)}</span>
|
||||
</div>
|
||||
<hr style="border: none; border-top: 2px solid #2c3e50; margin: 15px 0;">
|
||||
<div class="resumen-fila">
|
||||
<span class="resumen-label">💰 GANANCIA NETA ANUAL:</span>
|
||||
<span class="resumen-valor ${data.totales.ganancia_neta_total < 0 ? 'negativo' : ''}" style="font-size: 1.3em;">${formatoMoneda(data.totales.ganancia_neta_total)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
reporteContenido.innerHTML = html;
|
||||
}
|
||||
|
||||
// ========== INICIALIZACIÓN ==========
|
||||
|
||||
// Establecer valores por defecto
|
||||
const hoy = new Date();
|
||||
document.getElementById('fecha-diario').valueAsDate = hoy;
|
||||
|
||||
const semanaActual = obtenerSemanaActual();
|
||||
document.getElementById('semana-input').value = semanaActual;
|
||||
|
||||
const mesActual = hoy.toISOString().slice(0, 7);
|
||||
document.getElementById('mes-input').value = mesActual;
|
||||
|
||||
document.getElementById('anio-input').value = hoy.getFullYear();
|
||||
|
||||
// Cambiar parámetros según tipo de reporte
|
||||
tipoReporte.addEventListener('change', () => {
|
||||
document.querySelectorAll('.param-section').forEach(el => el.style.display = 'none');
|
||||
|
||||
const tipo = tipoReporte.value;
|
||||
if (tipo === 'diario') {
|
||||
document.getElementById('param-diario').style.display = 'block';
|
||||
} else if (tipo === 'semanal') {
|
||||
document.getElementById('param-semanal').style.display = 'block';
|
||||
} else if (tipo === 'mensual') {
|
||||
document.getElementById('param-mensual').style.display = 'block';
|
||||
} else if (tipo === 'anual') {
|
||||
document.getElementById('param-anual').style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
// Generar reporte
|
||||
generarBtn.addEventListener('click', async () => {
|
||||
const tipo = tipoReporte.value;
|
||||
let url = '../php/Obtener_Reporte.php?tipo_reporte=' + tipo;
|
||||
|
||||
// Agregar parámetros según el tipo
|
||||
if (tipo === 'diario') {
|
||||
const fecha = document.getElementById('fecha-diario').value;
|
||||
if (!fecha) {
|
||||
mostrarError('Por favor selecciona una fecha');
|
||||
return;
|
||||
}
|
||||
url += '&fecha=' + fecha;
|
||||
} else if (tipo === 'semanal') {
|
||||
const semana = document.getElementById('semana-input').value;
|
||||
if (!semana) {
|
||||
mostrarError('Por favor selecciona una semana');
|
||||
return;
|
||||
}
|
||||
url += '&semana=' + semana;
|
||||
} else if (tipo === 'mensual') {
|
||||
const mes = document.getElementById('mes-input').value;
|
||||
if (!mes) {
|
||||
mostrarError('Por favor selecciona un mes');
|
||||
return;
|
||||
}
|
||||
url += '&mes=' + mes;
|
||||
} else if (tipo === 'anual') {
|
||||
const anio = document.getElementById('anio-input').value;
|
||||
if (!anio) {
|
||||
mostrarError('Por favor selecciona un año');
|
||||
return;
|
||||
}
|
||||
url += '&anio=' + anio;
|
||||
}
|
||||
|
||||
ocultarError();
|
||||
mostrarSpinner();
|
||||
|
||||
try {
|
||||
const response = await fetch(url);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) {
|
||||
mostrarError(data.error);
|
||||
ocultarSpinner();
|
||||
return;
|
||||
}
|
||||
|
||||
ocultarSpinner();
|
||||
|
||||
// Generar nombres de archivo
|
||||
generarNombresYMetadatos(tipo, data);
|
||||
|
||||
// Renderizar según tipo
|
||||
if (tipo === 'diario') {
|
||||
renderizarDiario(data);
|
||||
} else if (tipo === 'semanal') {
|
||||
renderizarSemanal(data);
|
||||
} else if (tipo === 'mensual') {
|
||||
renderizarMensual(data);
|
||||
} else if (tipo === 'anual') {
|
||||
renderizarAnual(data);
|
||||
}
|
||||
|
||||
reporteContainer.style.display = 'block';
|
||||
exportarBtn.style.display = 'inline-block';
|
||||
} catch (error) {
|
||||
mostrarError('Error al cargar el reporte: ' + error.message);
|
||||
ocultarSpinner();
|
||||
}
|
||||
});
|
||||
|
||||
// Exportar a PDF
|
||||
exportarBtn.addEventListener('click', () => {
|
||||
const elemento = document.getElementById('reporte-contenido');
|
||||
const nombreArchivo = periodoActual.nombreArchivo;
|
||||
|
||||
const opciones = {
|
||||
margin: 10,
|
||||
filename: nombreArchivo + '.pdf',
|
||||
image: { type: 'jpeg', quality: 0.98 },
|
||||
html2canvas: { scale: 2, useCORS: true },
|
||||
jsPDF: { orientation: 'portrait', unit: 'mm', format: 'a4', compress: true }
|
||||
};
|
||||
|
||||
html2pdf()
|
||||
.set(opciones)
|
||||
.from(elemento)
|
||||
.save(nombreArchivo + '.pdf');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user