0% encontró este documento útil (0 votos)
3 vistas49 páginas

Reportes del Sistema Hidráulico

El documento es un código HTML que describe una interfaz para un sistema de reportes hidráulicos. Incluye secciones para filtros de búsqueda, estadísticas, y visualización de datos mediante tablas y gráficos. También contiene funcionalidades para exportar datos a formatos Excel y PDF, así como un diálogo para mostrar detalles adicionales.

Cargado por

Brayan Abad
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas49 páginas

Reportes del Sistema Hidráulico

El documento es un código HTML que describe una interfaz para un sistema de reportes hidráulicos. Incluye secciones para filtros de búsqueda, estadísticas, y visualización de datos mediante tablas y gráficos. También contiene funcionalidades para exportar datos a formatos Excel y PDF, así como un diálogo para mostrar detalles adicionales.

Cargado por

Brayan Abad
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOCX, PDF, TXT o lee en línea desde Scribd

<!

DOCTYPE html>

<html lang="es">

<head>

<meta charset="UTF-8" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<title>Reportes - Sistema Hidráulico</title>

<script src="[Link]

<script src="[Link]
[Link]"></script>

<script src="[Link]

<style>

:root {

--primary: #2c8d5d;

--accent: #3aa76d;

--light: #f9f9f9;

--dark: #2c3e50;

--danger: #e74c3c;

--warning: #f39c12;

--info: #3498db;

--border: #ccc;

* { box-sizing: border-box; }

body {

font-family: Arial, sans-serif;

margin: 0;

padding: 20px;

background-color: var(--light);

color: var(--dark);

header {

display: flex;
justify-content: space-between;

align-items: center;

margin-bottom: 20px;

header h1 {

margin: 0;

color: var(--primary);

.btn-back {

background-color: var(--dark);

color: white;

text-decoration: none;

padding: 8px 15px;

border-radius: 5px;

font-size: 14px;

.panel {

background: white;

padding: 20px;

border-radius: 8px;

box-shadow: 0 2px 4px rgba(0,0,0,0.1);

margin-bottom: 20px;

.filter-grid {

display: grid;

grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));

gap: 15px;

margin-bottom: 15px;

.filter-actions {

display: flex;
justify-content: flex-end;

gap: 10px;

margin-top: 15px;

label {

display: block;

margin-bottom: 5px;

font-weight: bold;

font-size: 0.9rem;

input, select {

padding: 8px;

border: 1px solid var(--border);

border-radius: 6px;

width: 100%;

transition: border 0.3s;

input:focus, select:focus {

outline: none;

border-color: var(--primary);

button {

background-color: var(--primary);

color: white;

border: none;

border-radius: 5px;

padding: 8px 15px;

cursor: pointer;

transition: background 0.3s;

font-size: 0.9rem;

}
button:hover {

background-color: var(--accent);

.tab-container {

margin-bottom: 20px;

.tabs {

display: flex;

border-bottom: 1px solid var(--border);

margin-bottom: 15px;

.tab {

padding: 10px 20px;

cursor: pointer;

border-bottom: 3px solid transparent;

transition: all 0.3s;

.[Link] {

font-weight: bold;

color: var(--primary);

border-bottom-color: var(--primary);

.tab-content {

display: none;

.[Link] {

display: block;

table {

width: 100%;

border-collapse: collapse;
margin-top: 15px;

font-size: 0.9rem;

th, td {

padding: 10px;

border-bottom: 1px solid #eee;

text-align: left;

th {

background-color: #f6f6f6;

font-weight: bold;

tr:hover {

background-color: #f9f9f9;

.stats-grid {

display: grid;

grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));

gap: 15px;

margin-bottom: 20px;

.stat-card {

background: white;

border-radius: 8px;

box-shadow: 0 2px 4px rgba(0,0,0,0.1);

padding: 15px;

text-align: center;

.stat-card .number {

font-size: 1.8rem;

font-weight: bold;
color: var(--primary);

margin: 10px 0;

.stat-card .label {

font-size: 0.9rem;

color: var(--dark);

.charts-container {

display: grid;

grid-template-columns: 1fr 1fr;

gap: 20px;

height: 300px;

margin-top: 20px;

.chart-container {

background: white;

border-radius: 8px;

box-shadow: 0 2px 4px rgba(0,0,0,0.1);

padding: 15px;

.pagination {

display: flex;

justify-content: center;

margin-top: 20px;

gap: 5px;

.pagination button {

background-color: white;

color: var(--dark);

border: 1px solid var(--border);

padding: 5px 10px;


}

.pagination [Link] {

background-color: var(--primary);

color: white;

border-color: var(--primary);

.pagination button:hover:not(.active) {

background-color: #f1f1f1;

.status {

padding: 5px 10px;

border-radius: 15px;

font-size: 0.8rem;

font-weight: bold;

text-align: center;

.status-pendiente {

background-color: #ffeaa7;

color: #b7791f;

.status-pagado {

background-color: #c6f6d5;

color: #2f855a;

.status-parcial {

background-color: #bee3f8;

color: #2b6cb0;

.secondary-button {

background-color: #6c757d;

}
.secondary-button:hover {

background-color: #5a6268;

.info-button {

background-color: var(--info);

.info-button:hover {

background-color: #2980b9;

.warning-button {

background-color: var(--warning);

.warning-button:hover {

background-color: #e67e22;

.text-right {

text-align: right;

.empty-message {

text-align: center;

padding: 30px;

font-style: italic;

color: #777;

.loading {

text-align: center;

padding: 30px;

#detalleDialog {

display: none;

position: fixed;
top: 0;

left: 0;

right: 0;

bottom: 0;

background-color: rgba(0,0,0,0.5);

z-index: 1000;

justify-content: center;

align-items: center;

.dialog-content {

background: white;

border-radius: 8px;

box-shadow: 0 4px 15px rgba(0,0,0,0.2);

padding: 25px;

width: 90%;

max-width: 600px;

max-height: 80vh;

overflow-y: auto;

.dialog-header {

display: flex;

justify-content: space-between;

align-items: center;

margin-bottom: 15px;

.dialog-header h3 {

margin: 0;

color: var(--primary);

.close-button {

background: none;
border: none;

font-size: 1.5rem;

color: #777;

cursor: pointer;

.close-button:hover {

color: var(--danger);

.detail-row {

display: flex;

margin-bottom: 10px;

border-bottom: 1px solid #eee;

padding-bottom: 10px;

.detail-label {

flex: 0 0 40%;

font-weight: bold;

.detail-value {

flex: 0 0 60%;

@media print {

.no-print {

display: none !important;

body {

padding: 0;

background: white;

.panel {

box-shadow: none;
margin: 0;

padding: 0;

</style>

</head>

<body>

<header class="no-print">

<h1>Reportes del Sistema</h1>

<a href="#" class="btn-back" onclick="[Link]()">Volver al Registro</a>

</header>

<!-- Panel de filtros -->

<div class="panel no-print">

<h2>Filtros de Búsqueda</h2>

<div class="filter-grid">

<div>

<label for="filtroUsuario">Usuario:</label>

<input type="text" id="filtroUsuario" placeholder="Nombre o apellido">

</div>

<div>

<label for="filtroDni">DNI:</label>

<input type="text" id="filtroDni" placeholder="DNI del usuario">

</div>

<div>

<label for="filtroCampana">Campaña:</label>

<select id="filtroCampana">

<option value="">Todas</option>

<option value="2023-1">2023-1</option>

<option value="2023-2">2023-2</option>

<option value="2024-1">2024-1</option>
<option value="2024-2">2024-2</option>

</select>

</div>

<div>

<label for="filtroCanal">Canal:</label>

<select id="filtroCanal">

<option value="">Todos</option>

<option value="Canal 1">Canal 1</option>

<option value="Canal 2">Canal 2</option>

<option value="Canal 3">Canal 3</option>

</select>

</div>

<div>

<label for="filtroFechaDesde">Fecha desde:</label>

<input type="date" id="filtroFechaDesde">

</div>

<div>

<label for="filtroFechaHasta">Fecha hasta:</label>

<input type="date" id="filtroFechaHasta">

</div>

<div>

<label for="filtroEstado">Estado:</label>

<select id="filtroEstado">

<option value="">Todos</option>

<option value="pagado">Pagado</option>

<option value="pendiente">Pendiente</option>

<option value="parcial">Pago Parcial</option>

</select>

</div>

</div>

<div class="filter-actions">
<button onclick="limpiarFiltros()" class="secondary-button">Limpiar Filtros</button>

<button onclick="aplicarFiltros()">Buscar</button>

</div>

</div>

<!-- Estadísticas generales -->

<div class="stats-grid no-print">

<div class="stat-card">

<div class="label">Total Usuarios</div>

<div class="number" id="statUsuarios">0</div>

</div>

<div class="stat-card">

<div class="label">Total Pagos</div>

<div class="number" id="statPagos">0</div>

</div>

<div class="stat-card">

<div class="label">Total Recaudado</div>

<div class="number" id="statRecaudado">S/. 0.00</div>

</div>

<div class="stat-card">

<div class="label">Total Pendiente</div>

<div class="number" id="statPendiente">S/. 0.00</div>

</div>

</div>

<!-- Contenedor de pestañas -->

<div class="tab-container panel">

<div class="tabs no-print">

<div class="tab active" data-tab="tabPagos">Registro de Pagos</div>

<div class="tab" data-tab="tabDeudas">Estado de Deudas</div>

<div class="tab" data-tab="tabEstadisticas">Estadísticas</div>


</div>

<!-- Contenido de pestaña: Pagos -->

<div id="tabPagos" class="tab-content active">

<div class="filter-actions no-print">

<button onclick="exportarPagosExcel()" class="warning-button">Exportar Excel</button>

<button onclick="exportarPagosPDF()" class="info-button">Exportar PDF</button>

</div>

<div id="tablaPagos">

<table>

<thead>

<tr>

<th>ID</th>

<th>Fecha</th>

<th>Usuario</th>

<th>DNI</th>

<th>Campaña</th>

<th>Canal</th>

<th>Monto</th>

<th class="no-print">Acciones</th>

</tr>

</thead>

<tbody id="bodyTablaPagos">

<tr>

<td colspan="8" class="loading">Cargando datos...</td>

</tr>

</tbody>

</table>

<div class="pagination no-print" id="paginacionPagos"></div>

</div>
</div>

<!-- Contenido de pestaña: Deudas -->

<div id="tabDeudas" class="tab-content">

<div class="filter-actions no-print">

<button onclick="exportarDeudasExcel()" class="warning-button">Exportar Excel</button>

<button onclick="exportarDeudasPDF()" class="info-button">Exportar PDF</button>

</div>

<div id="tablaDeudas">

<table>

<thead>

<tr>

<th>Usuario</th>

<th>DNI</th>

<th>Campaña</th>

<th>Canal</th>

<th>Total</th>

<th>Pagado</th>

<th>Saldo</th>

<th>Estado</th>

<th class="no-print">Acciones</th>

</tr>

</thead>

<tbody id="bodyTablaDeudas">

<tr>

<td colspan="9" class="loading">Cargando datos...</td>

</tr>

</tbody>

</table>

<div class="pagination no-print" id="paginacionDeudas"></div>


</div>

</div>

<!-- Contenido de pestaña: Estadísticas -->

<div id="tabEstadisticas" class="tab-content">

<div class="charts-container">

<div class="chart-container">

<h3>Pagos por Canal</h3>

<canvas id="chartCanales"></canvas>

</div>

<div class="chart-container">

<h3>Pagos por Campaña</h3>

<canvas id="chartCampanas"></canvas>

</div>

</div>

<div class="charts-container" style="margin-top: 20px;">

<div class="chart-container">

<h3>Deudas por Tipo de Cultivo</h3>

<canvas id="chartCultivos"></canvas>

</div>

<div class="chart-container">

<h3>Pagos por Mes</h3>

<canvas id="chartMeses"></canvas>

</div>

</div>

</div>

</div>

<!-- Diálogo de detalles -->

<div id="detalleDialog">

<div class="dialog-content">
<div class="dialog-header">

<h3 id="detalleTitle">Detalles</h3>

<button class="close-button" onclick="cerrarDetalle()">&times;</button>

</div>

<div id="detalleContent"></div>

<div class="filter-actions no-print">

<button onclick="cerrarDetalle()" class="secondary-button">Cerrar</button>

<button id="btnDetallePDF" class="info-button">Exportar a PDF</button>

</div>

</div>

</div>

<script>

const { jsPDF } = [Link];

// Constantes

const POZA_PRICES = {

arroz: 16,

maiz: 10,

panLlevar: 10,

pastos: 16,

maracuya: 8,

limon: 8

};

const CULTIVOS_LABELS = {

arroz: "Arroz",

maiz: "Maíz",

panLlevar: "Pan llevar",

pastos: "Pastos",

maracuya: "Maracuyá",
limon: "Limón"

};

// Variables globales

let pagos = [Link]([Link]('pagos')) || [];

let deudas = [Link]([Link]('deudas')) || [];

// Variables para paginación

const ITEMS_PER_PAGE = 10;

let currentPagePagos = 1;

let currentPageDeudas = 1;

let filteredPagos = [...pagos];

let filteredDeudas = [...deudas];

// Variables para gráficos

let chartCanales, chartCampanas, chartCultivos, chartMeses;

// Inicialización

[Link]('DOMContentLoaded', () => {

// Configurar pestañas

setupTabs();

// Cargar datos iniciales

cargarDatosPagos();

cargarDatosDeudas();

cargarEstadisticas();

actualizarEstadisticasGenerales();

// Establecer fechas por defecto (último mes)

const hoy = new Date();

const mesAnterior = new Date();


[Link]([Link]() - 1);

[Link]('filtroFechaDesde').valueAsDate = mesAnterior;

[Link]('filtroFechaHasta').valueAsDate = hoy;

});

// Configuración de pestañas

function setupTabs() {

const tabs = [Link]('.tab');

[Link](tab => {

[Link]('click', () => {

// Desactivar todas las pestañas

[Link](t => [Link]('active'));

// Ocultar todos los contenidos

[Link]('.tab-content').forEach(content => {

[Link]('active');

});

// Activar la pestaña clickeada

[Link]('active');

// Mostrar el contenido correspondiente

const tabId = [Link]('data-tab');

[Link](tabId).[Link]('active');

// Si es la pestaña de estadísticas, actualizar gráficos

if (tabId === 'tabEstadisticas') {

actualizarGraficos();

});
});

// Aplicar filtros

function aplicarFiltros() {

const usuario = [Link]('filtroUsuario').[Link]();

const dni = [Link]('filtroDni').value;

const campana = [Link]('filtroCampana').value;

const canal = [Link]('filtroCanal').value;

const fechaDesde = [Link]('filtroFechaDesde').value ? new


Date([Link]('filtroFechaDesde').value) : null;

const fechaHasta = [Link]('filtroFechaHasta').value ? new


Date([Link]('filtroFechaHasta').value + 'T23:59:59') : null;

const estado = [Link]('filtroEstado').value;

// Filtrar pagos

filteredPagos = [Link](pago => {

// Convertir fecha del pago a objeto Date

const fechaPago = new Date([Link]);

// Aplicar filtros

if (usuario && ![Link]().includes(usuario)) return false;

if (dni && [Link] !== dni) return false;

if (campana && [Link] !== campana) return false;

if (canal && [Link] !== canal) return false;

if (fechaDesde && fechaPago < fechaDesde) return false;

if (fechaHasta && fechaPago > fechaHasta) return false;

return true;

});

// Filtrar deudas
filteredDeudas = [Link](deuda => {

// Para el estado

let estadoDeuda = "";

if ([Link] <= 0) estadoDeuda = "pagado";

else if ([Link] > 0) estadoDeuda = "parcial";

else estadoDeuda = "pendiente";

// Aplicar filtros

if (usuario && ![Link]().includes(usuario)) return false;

if (dni && [Link] !== dni) return false;

if (campana && [Link] !== campana) return false;

if (canal && [Link] !== canal) return false;

if (estado && estadoDeuda !== estado) return false;

return true;

});

// Resetear paginación y mostrar resultados

currentPagePagos = 1;

currentPageDeudas = 1;

cargarDatosPagos();

cargarDatosDeudas();

actualizarEstadisticasGenerales();

actualizarGraficos();

// Limpiar filtros

function limpiarFiltros() {

[Link]('filtroUsuario').value = '';

[Link]('filtroDni').value = '';
[Link]('filtroCampana').value = '';

[Link]('filtroCanal').value = '';

[Link]('filtroFechaDesde').value = '';

[Link]('filtroFechaHasta').value = '';

[Link]('filtroEstado').value = '';

// Restaurar datos sin filtros

filteredPagos = [...pagos];

filteredDeudas = [...deudas];

// Resetear paginación y mostrar resultados

currentPagePagos = 1;

currentPageDeudas = 1;

cargarDatosPagos();

cargarDatosDeudas();

actualizarEstadisticasGenerales();

actualizarGraficos();

// Cargar datos de pagos

function cargarDatosPagos() {

const tbody = [Link]('bodyTablaPagos');

const startIndex = (currentPagePagos - 1) * ITEMS_PER_PAGE;

const paginatedItems = filteredPagos

.sort((a, b) => new Date([Link]) - new Date([Link]))

.slice(startIndex, startIndex + ITEMS_PER_PAGE);

if ([Link] === 0) {

[Link] = '<tr><td colspan="8" class="empty-message">No se encontraron


registros de pagos</td></tr>';
[Link]('paginacionPagos').innerHTML = '';

return;

let html = '';

[Link](pago => {

// Formatear fecha para mostrar

const fechaParts = [Link](',')[0].split('/');

const fechaFormateada = [Link] === 3

? `${fechaParts[1].padStart(2, '0')}/${fechaParts[0].padStart(2, '0')}/${fechaParts[2]}`

: [Link](',')[0];

html += `

<tr>

<td>${[Link]().slice(-6)}</td>

<td>${fechaFormateada}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td class="text-right">S/. ${[Link](2)}</td>

<td class="no-print">

<button onclick="verDetallePago(${[Link]})" class="info-button">Detalles</button>

</td>

</tr>

`;

});

[Link] = html;

// Actualizar paginación
actualizarPaginacion('paginacionPagos', [Link], currentPagePagos,
cambiarPaginaPagos);

// Cargar datos de deudas

function cargarDatosDeudas() {

const tbody = [Link]('bodyTablaDeudas');

const startIndex = (currentPageDeudas - 1) * ITEMS_PER_PAGE;

const paginatedItems = [Link](startIndex, startIndex + ITEMS_PER_PAGE);

if ([Link] === 0) {

[Link] = '<tr><td colspan="9" class="empty-message">No se encontraron


registros de deudas</td></tr>';

[Link]('paginacionDeudas').innerHTML = '';

return;

let html = '';

[Link](deuda => {

let estadoClase = '';

let estadoTexto = '';

if ([Link] <= 0) {

estadoClase = 'status-pagado';

estadoTexto = 'Pagado';

} else if ([Link] > 0) {

estadoClase = 'status-parcial';

estadoTexto = 'Parcial';

} else {

estadoClase = 'status-pendiente';

estadoTexto = 'Pendiente';

}
html += `

<tr>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td>${[Link]}</td>

<td class="text-right">S/. ${[Link](2)}</td>

<td class="text-right">S/. ${[Link](2)}</td>

<td class="text-right">S/. ${[Link](2)}</td>

<td><div class="status ${estadoClase}">${estadoTexto}</div></td>

<td class="no-print">

<button onclick="verDetalleDeuda(${[Link]})"
class="info-button">Detalles</button>

</td>

</tr>

`;

});

[Link] = html;

// Actualizar paginación

actualizarPaginacion('paginacionDeudas', [Link], currentPageDeudas,


cambiarPaginaDeudas);

// Funciones de paginación

// Continúa desde la parte donde termina el código anterior

// Funciones de paginación (continuación)

function actualizarPaginacion(containerId, totalItems, currentPage, changePageFunction) {


const container = [Link](containerId);

const totalPages = [Link](totalItems / ITEMS_PER_PAGE);

if (totalPages <= 1) {

[Link] = '';

return;

let html = '';

// Botón anterior

html += `<button ${currentPage === 1 ? 'disabled' : ''} onclick="${[Link]}


(${currentPage - 1})">«</button>`;

// Páginas

for (let i = 1; i <= totalPages; i++) {

if (

i === 1 || // Primera página

i === totalPages || // Última página

(i >= currentPage - 2 && i <= currentPage + 2) // 2 páginas antes y después de la actual

){

html += `<button class="${i === currentPage ? 'active' : ''}" onclick="$


{[Link]}(${i})">${i}</button>`;

} else if (i === currentPage - 3 || i === currentPage + 3) {

html += '<span>...</span>';

// Botón siguiente

html += `<button ${currentPage === totalPages ? 'disabled' : ''} onclick="$


{[Link]}(${currentPage + 1})">»</button>`;
[Link] = html;

function cambiarPaginaPagos(page) {

currentPagePagos = page;

cargarDatosPagos();

function cambiarPaginaDeudas(page) {

currentPageDeudas = page;

cargarDatosDeudas();

// Cargar estadísticas generales

function actualizarEstadisticasGenerales() {

// Calcular total de usuarios únicos

const usuarios = new Set();

[Link](deuda => [Link]([Link]));

[Link]('statUsuarios').textContent = [Link];

// Calcular total de pagos

[Link]('statPagos').textContent = [Link];

// Calcular total recaudado

const totalRecaudado = [Link]((sum, pago) => sum + [Link], 0);

[Link]('statRecaudado').textContent = `S/. ${[Link](2)}`;

// Calcular total pendiente

const totalPendiente = [Link]((sum, deuda) => sum + [Link], 0);

[Link]('statPendiente').textContent = `S/. ${[Link](2)}`;

}
// Actualizar gráficos

function actualizarGraficos() {

// Destruir gráficos anteriores si existen

if (chartCanales) [Link]();

if (chartCampanas) [Link]();

if (chartCultivos) [Link]();

if (chartMeses) [Link]();

// Datos para gráfico de canales

const datosCanales = procesarDatosParaGrafico(filteredPagos, 'canal');

chartCanales = crearGrafico('chartCanales', 'doughnut',

'Distribución de Pagos por Canal',

[Link],

[Link]

);

// Datos para gráfico de campañas

const datosCampanas = procesarDatosParaGrafico(filteredPagos, 'campana');

chartCampanas = crearGrafico('chartCampanas', 'bar',

'Distribución de Pagos por Campaña',

[Link],

[Link]

);

// Datos para gráfico de cultivos

const datosCultivos = procesarDatosCultivos();

chartCultivos = crearGrafico('chartCultivos', 'pie',

'Distribución de Deudas por Tipo de Cultivo',

[Link],

[Link]
);

// Datos para gráfico de meses

const datosMeses = procesarDatosPorMes();

chartMeses = crearGrafico('chartMeses', 'line',

'Evolución de Pagos por Mes',

[Link],

[Link],

{ borderColor: 'rgba(75, 192, 192, 1)', tension: 0.1 }

);

// Procesar datos para gráficos

function procesarDatosParaGrafico(datos, campo) {

const agrupado = {};

[Link](item => {

const valor = item[campo];

if (!agrupado[valor]) {

agrupado[valor] = 0;

agrupado[valor] += [Link];

});

return {

labels: [Link](agrupado),

data: [Link](agrupado)

};

function procesarDatosCultivos() {
const agrupado = {};

// Inicializar con todos los tipos de cultivo

[Link](CULTIVOS_LABELS).forEach(key => {

agrupado[CULTIVOS_LABELS[key]] = 0;

});

// Sumar deudas por tipo de cultivo

[Link](deuda => {

if ([Link]) {

[Link]([Link]).forEach(cultivo => {

if ([Link][cultivo] > 0) {

const cultivoLabel = CULTIVOS_LABELS[cultivo];

agrupado[cultivoLabel] = (agrupado[cultivoLabel] || 0) + ([Link] *


[Link][cultivo] / 100);

});

});

// Filtrar los que tienen valor 0

const labels = [];

const data = [];

[Link](agrupado).forEach(key => {

if (agrupado[key] > 0) {

[Link](key);

[Link](agrupado[key]);

});
return { labels, data };

function procesarDatosPorMes() {

const meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];

const datosPorMes = Array(12).fill(0);

[Link](pago => {

const fecha = new Date([Link]);

const mes = [Link]();

datosPorMes[mes] += [Link];

});

return {

labels: meses,

data: datosPorMes

};

// Crear gráfico

function crearGrafico(canvasId, tipo, titulo, labels, datos, opciones = {}) {

const ctx = [Link](canvasId).getContext('2d');

// Colores predefinidos

const colores = [

'rgba(255, 99, 132, 0.7)',

'rgba(54, 162, 235, 0.7)',

'rgba(255, 206, 86, 0.7)',

'rgba(75, 192, 192, 0.7)',

'rgba(153, 102, 255, 0.7)',

'rgba(255, 159, 64, 0.7)',


'rgba(255, 99, 132, 0.7)',

'rgba(54, 162, 235, 0.7)',

'rgba(255, 206, 86, 0.7)',

'rgba(75, 192, 192, 0.7)'

];

const config = {

type: tipo,

data: {

labels: labels,

datasets: [{

label: titulo,

data: datos,

backgroundColor: tipo === 'line' ? 'rgba(75, 192, 192, 0.2)' : [Link](0, [Link]),

borderColor: tipo === 'line' ? [Link] || 'rgba(75, 192, 192, 1)' :


[Link](0, [Link]),

borderWidth: 1,

fill: tipo === 'line',

tension: [Link] || 0

}]

},

options: {

responsive: true,

maintainAspectRatio: false,

plugins: {

legend: {

position: tipo === 'doughnut' || tipo === 'pie' ? 'right' : 'top',

},

title: {

display: false,

text: titulo
}

};

return new Chart(ctx, config);

// Ver detalle de pago

function verDetallePago(id) {

const pago = [Link](p => [Link] === id);

if (!pago) return;

const detalleTitle = [Link]('detalleTitle');

const detalleContent = [Link]('detalleContent');

[Link] = `Detalle de Pago #${[Link]().slice(-6)}`;

// Formatear fecha para mostrar

const fechaParts = [Link](',')[0].split('/');

const fechaFormateada = [Link] === 3

? `${fechaParts[1].padStart(2, '0')}/${fechaParts[0].padStart(2, '0')}/${fechaParts[2]}`

: [Link](',')[0];

let html = `

<div class="detail-row">

<div class="detail-label">ID de Pago:</div>

<div class="detail-value">${[Link]().slice(-6)}</div>

</div>

<div class="detail-row">

<div class="detail-label">Fecha:</div>
<div class="detail-value">${fechaFormateada}</div>

</div>

<div class="detail-row">

<div class="detail-label">Usuario:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">DNI:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Campaña:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Canal:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Monto:</div>

<div class="detail-value">S/. ${[Link](2)}</div>

</div>

<div class="detail-row">

<div class="detail-label">Método de Pago:</div>

<div class="detail-value">${[Link] || 'Efectivo'}</div>

</div>

`;

// Si hay observaciones

if ([Link]) {

html += `
<div class="detail-row">

<div class="detail-label">Observaciones:</div>

<div class="detail-value">${[Link]}</div>

</div>

`;

[Link] = html;

// Configurar botón de PDF

[Link]('btnDetallePDF').onclick = () => exportarDetallePagoPDF(pago);

// Mostrar diálogo

[Link]('detalleDialog').[Link] = 'flex';

// Ver detalle de deuda

function verDetalleDeuda(id) {

const deuda = [Link](d => [Link] === id);

if (!deuda) return;

const detalleTitle = [Link]('detalleTitle');

const detalleContent = [Link]('detalleContent');

[Link] = `Detalle de Deuda - ${[Link]}`;

// Calcular porcentaje de pago

const porcentajePago = ([Link] / [Link]) * 100;

let estadoTexto = '';

if ([Link] <= 0) {
estadoTexto = '<span class="status status-pagado">Pagado</span>';

} else if ([Link] > 0) {

estadoTexto = '<span class="status status-parcial">Pago Parcial</span>';

} else {

estadoTexto = '<span class="status status-pendiente">Pendiente</span>';

let html = `

<div class="detail-row">

<div class="detail-label">Usuario:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">DNI:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Campaña:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Canal:</div>

<div class="detail-value">${[Link]}</div>

</div>

<div class="detail-row">

<div class="detail-label">Total a Pagar:</div>

<div class="detail-value">S/. ${[Link](2)}</div>

</div>

<div class="detail-row">

<div class="detail-label">Monto Pagado:</div>


<div class="detail-value">S/. ${[Link](2)} (${[Link](1)}
%)</div>

</div>

<div class="detail-row">

<div class="detail-label">Saldo Pendiente:</div>

<div class="detail-value">S/. ${[Link](2)}</div>

</div>

<div class="detail-row">

<div class="detail-label">Estado:</div>

<div class="detail-value">${estadoTexto}</div>

</div>

`;

// Si hay cultivos

if ([Link]) {

html += `

<div class="detail-row">

<div class="detail-label">Distribución por Cultivos:</div>

<div class="detail-value">

<table style="width:100%; margin-top: 10px;">

<thead>

<tr>

<th>Cultivo</th>

<th>Porcentaje</th>

<th>Monto</th>

</tr>

</thead>

<tbody>

`;

[Link]([Link]).forEach(cultivo => {
if ([Link][cultivo] > 0) {

const montoCultivo = ([Link] * [Link][cultivo] / 100).toFixed(2);

html += `

<tr>

<td>${CULTIVOS_LABELS[cultivo]}</td>

<td>${[Link][cultivo]}%</td>

<td>S/. ${montoCultivo}</td>

</tr>

`;

});

html += `

</tbody>

</table>

</div>

</div>

`;

// Historial de pagos

const pagosDeLaDeuda = [Link](p => [Link] === [Link]);

if ([Link] > 0) {

html += `

<div class="detail-row">

<div class="detail-label">Historial de Pagos:</div>

<div class="detail-value">

<table style="width:100%; margin-top: 10px;">

<thead>

<tr>
<th>Fecha</th>

<th>Monto</th>

<th>Método</th>

</tr>

</thead>

<tbody>

`;

[Link](pago => {

const fechaParts = [Link](',')[0].split('/');

const fechaFormateada = [Link] === 3

? `${fechaParts[1].padStart(2, '0')}/${fechaParts[0].padStart(2, '0')}/${fechaParts[2]}`

: [Link](',')[0];

html += `

<tr>

<td>${fechaFormateada}</td>

<td>S/. ${[Link](2)}</td>

<td>${[Link] || 'Efectivo'}</td>

</tr>

`;

});

html += `

</tbody>

</table>

</div>

</div>

`;

}
[Link] = html;

// Configurar botón de PDF

[Link]('btnDetallePDF').onclick = () => exportarDetalleDeudaPDF(deuda);

// Mostrar diálogo

[Link]('detalleDialog').[Link] = 'flex';

// Cerrar diálogo de detalles

function cerrarDetalle() {

[Link]('detalleDialog').[Link] = 'none';

// Función para exportar datos a PDF

function exportarPagosPDF() {

const doc = new jsPDF();

// Título

[Link](18);

[Link]('Registro de Pagos - Sistema Hidráulico', 14, 20);

// Información de filtros aplicados

[Link](10);

let filtrosTexto = 'Filtros aplicados: ';

let hayFiltros = false;

if ([Link]('filtroUsuario').value) {

filtrosTexto += `Usuario: ${[Link]('filtroUsuario').value}; `;

hayFiltros = true;

}
if ([Link]('filtroDni').value) {

filtrosTexto += `DNI: ${[Link]('filtroDni').value}; `;

hayFiltros = true;

if ([Link]('filtroCampana').value) {

filtrosTexto += `Campaña: ${[Link]('filtroCampana').value}; `;

hayFiltros = true;

if ([Link]('filtroCanal').value) {

filtrosTexto += `Canal: ${[Link]('filtroCanal').value}; `;

hayFiltros = true;

if ([Link]('filtroFechaDesde').value) {

filtrosTexto += `Desde: ${[Link]('filtroFechaDesde').value}; `;

hayFiltros = true;

if ([Link]('filtroFechaHasta').value) {

filtrosTexto += `Hasta: ${[Link]('filtroFechaHasta').value}; `;

hayFiltros = true;

if (!hayFiltros) {

filtrosTexto += 'Ninguno';

[Link](filtrosTexto, 14, 30);


// Información de estadísticas

[Link](`Total de pagos: ${[Link]}`, 14, 38);

[Link](`Total recaudado: S/. ${[Link]((sum, p) => sum + [Link],


0).toFixed(2)}`, 14, 46);

// Fecha de generación

const ahora = new Date();

[Link](`Fecha de generación: ${[Link]()} ${[Link]()}`,


14, 54);

// Tabla de datos

const columns = ['ID', 'Fecha', 'Usuario', 'DNI', 'Campaña', 'Canal', 'Monto'];

const data = [Link](pago => {

const fechaParts = [Link](',')[0].split('/');

const fechaFormateada = [Link] === 3

? `${fechaParts[1].padStart(2, '0')}/${fechaParts[0].padStart(2, '0')}/${fechaParts[2]}`

: [Link](',')[0];

return [

[Link]().slice(-6),

fechaFormateada,

[Link],

[Link],

[Link],

[Link],

`S/. ${[Link](2)}`

];

});

[Link]({
startY: 60,

head: [columns],

body: data,

theme: 'grid',

styles: { fontSize: 8 },

headStyles: { fillColor: [44, 141, 93] }

});

// Guardar PDF

[Link]('registro_pagos.pdf');

function exportarDeudasPDF() {

const doc = new jsPDF();

// Título

[Link](18);

[Link]('Estado de Deudas - Sistema Hidráulico', 14, 20);

// Información de filtros aplicados

[Link](10);

let filtrosTexto = 'Filtros aplicados: ';

let hayFiltros = false;

if ([Link]('filtroUsuario').value) {

filtrosTexto += `Usuario: ${[Link]('filtroUsuario').value}; `;

hayFiltros = true;

if ([Link]('filtroDni').value) {

filtrosTexto += `DNI: ${[Link]('filtroDni').value}; `;


hayFiltros = true;

if ([Link]('filtroCampana').value) {

filtrosTexto += `Campaña: ${[Link]('filtroCampana').value}; `;

hayFiltros = true;

if ([Link]('filtroCanal').value) {

filtrosTexto += `Canal: ${[Link]('filtroCanal').value}; `;

hayFiltros = true;

if ([Link]('filtroEstado').value) {

filtrosTexto += `Estado: ${[Link]('filtroEstado').value}; `;

hayFiltros = true;

if (!hayFiltros) {

filtrosTexto += 'Ninguno';

[Link](filtrosTexto, 14, 30);

// Información de estadísticas

[Link](`Total de usuarios: ${new Set([Link](d => [Link])).size}`, 14, 38);

[Link](`Total pendiente: S/. ${[Link]((sum, d) => sum + [Link],


0).toFixed(2)}`, 14, 46);

// Fecha de generación

const ahora = new Date();


[Link](`Fecha de generación: ${[Link]()} ${[Link]()}`,
14, 54);

// Tabla de datos

const columns = ['Usuario', 'DNI', 'Campaña', 'Canal', 'Total', 'Pagado', 'Saldo', 'Estado'];

const data = [Link](deuda => {

let estado = '';

if ([Link] <= 0) estado = 'Pagado';

else if ([Link] > 0) estado = 'Parcial';

else estado = 'Pendiente';

return [

[Link],

[Link],

[Link],

[Link],

`S/. ${[Link](2)}`,

`S/. ${[Link](2)}`,

`S/. ${[Link](2)}`,

estado

];

});

[Link]({

startY: 60,

head: [columns],

body: data,

theme: 'grid',

styles: { fontSize: 8 },

headStyles: { fillColor: [44, 141, 93] }


});

// Guardar PDF

[Link]('estado_deudas.pdf');

// Exportar detalle específico a PDF

function exportarDetallePagoPDF(pago) {

const doc = new jsPDF();

// Formatear fecha para mostrar

const fechaParts = [Link](',')[0].split('/');

const fechaFormateada = [Link] === 3

? `${fechaParts[1].padStart(2, '0')}/${fechaParts[0].padStart(2, '0')}/${fechaParts[2]}`

: [Link](',')[0];

// Título

[Link](18);

[Link](`Comprobante de Pago #${[Link]().slice(-6)}`, 14, 20);

// Información del pago

[Link](12);

[Link](`Fecha: ${fechaFormateada}`, 14, 35);

[Link](`Usuario: ${[Link]}`, 14, 45);

[Link](`DNI: ${[Link]}`, 14, 55);

[Link](`Campaña: ${[Link]}`, 14, 65);

[Link](`Canal: ${[Link]}`, 14, 75);

[Link](`Método de pago: ${[Link] || 'Efectivo'}`, 14, 85);

// Total del pago

[Link](16);
[Link](`Total pagado: S/. ${[Link](2)}`, 14, 100);

// Observaciones

if ([Link]) {

[Link](12);

[Link]('Observaciones:', 14, 115);

[Link](10);

// Dividir texto largo en múltiples líneas

const splitText = [Link]([Link], 180);

[Link](splitText, 14, 125);

// Firma y sello

[Link](10);

[Link]('Firma y Sello', 80, 200);

[Link](50, 210, 150, 210);

// Fecha de generación

const ahora = new Date();

[Link](8);

[Link](`Documento generado el ${[Link]()} a las $


{[Link]()}`, 14, 230);

[Link]('Este documento no tiene valor fiscal. Solicite su comprobante oficial.', 14, 237);

// Guardar PDF

[Link](`pago_${[Link]}_${[Link](/\s+/g, '_')}.pdf`);

function exportarDetalleDeudaPDF(deuda) {

const doc = new jsPDF();


// Título

[Link](18);

[Link](`Estado de Cuenta - ${[Link]}`, 14, 20);

// Información de la deuda

[Link](12);

[Link](`Usuario: ${[Link]}`, 14, 35);

[Link](`DNI: ${[Link]}`, 14, 45);

[Link](`Campaña: ${[Link]}`, 14, 55);

[Link](`Canal: ${[Link]}`, 14, 65);

// Estado financiero

[Link](`Total a pagar: S/. ${[Link](2)}`, 14, 80);

[Link](`Monto pagado: S/. ${[Link](2)}`, 14, 90);

[Link](`Saldo pendiente: S/. ${[Link](2)}`, 14, 100);

// Estado

let estado = '';

if ([Link] <= 0) estado = 'Pagado';

else if ([Link] > 0) estado = 'Pago Parcial';

else estado = 'Pendiente';

[Link](`Estado: ${estado}`, 14, 110);

// Cultivos si existen

let yPos = 125;

if ([Link]) {

[Link]('Distribución por cultivos:', 14, yPos);

yPos += 10;
const

También podría gustarte