<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Fiscal</title>
<script src="<https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js>"></script>
<style>
:root {
--primary: #0066cc;
--secondary: #004080;
--accent: #00a1e0;
--background: #f5f7fa;
--dark: #333;
--light: #fff;
--success: #28a745;
--warning: #ffc107;
--danger: #dc3545;
--gray-light: #f1f2f6;
--gray: #dfe1e5;
--text: #333;
--text-light: #666;
--border-radius: 8px;
--box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background-color: var(--background);
color: var(--text);
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.header {
background: linear-gradient(to right, var(--primary), var(--secondary));
color: var(--light);
padding: 1rem 1.5rem; /* Ajuste de padding */
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap; /* Permite que los elementos se envuelvan en pantallas pequeñas */
}
.logo img {
height: 50px; /* Ajuste de tamaño para móvil */
margin-right: 0.5rem;
}
.logo-container {
display: flex;
align-items: center;
margin-bottom: 0.5rem; /* Espacio debajo en móvil */
}
.logo-text {
font-weight: 700;
font-size: 1.3rem; /* Ajuste de tamaño para móvil */
}
.user-info {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 0.5rem; /* Espacio debajo en móvil */
}
.user-name {
font-size: 0.9rem; /* Ajuste de tamaño para móvil */
}
.user-icon {
background-color: var(--light);
color: var(--primary);
width: 35px; /* Ajuste de tamaño para móvil */
height: 35px; /* Ajuste de tamaño para móvil */
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px; /* Ajuste de tamaño para móvil */
}
.container {
display: grid;
grid-template-columns: 250px 1fr; /* Layout por defecto para pantallas grandes */
flex-grow: 1;
}
.sidebar {
background-color: var(--light);
padding: 1.5rem;
border-right: 1px solid var(--gray);
}
.menu {
list-style: none;
}
.menu-item {
margin-bottom: 0.5rem;
padding: 0.8rem 1rem;
border-radius: var(--border-radius);
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--text);
font-size: 0.95rem; /* Ajuste de tamaño */
}
.menu-item:hover {
background-color: var(--gray-light);
}
.menu-item.active {
background-color: var(--primary);
color: var(--light);
}
.main-content {
padding: 1.5rem;
overflow-y: auto;
}
.page-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 1.5rem;
color: var(--primary);
}
.dashboard-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); /* Ajuste minmax */
gap: 1.5rem;
margin-bottom: 1.5rem;
}
.card {
background-color: var(--light);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
padding: 1.5rem;
transition: var(--transition);
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.card-title {
font-size: 1.1rem;
font-weight: 600;
color: var(--text);
}
.card-icon {
background-color: var(--gray-light);
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--primary);
font-size: 20px;
}
.highlight-card {
background: linear-gradient(135deg, var(--primary), var(--accent));
color: var(--light);
}
.highlight-card .card-icon {
background-color: rgba(255, 255, 255, 0.2);
color: var(--light);
}
.highlight-card .card-title,
.highlight-card .stat-value,
.highlight-card .stat-label {
color: var(--light);
}
.stat-value {
font-size: 1.8rem; /* Ajuste de tamaño */
font-weight: 700;
margin: 0.5rem 0;
}
.stat-label {
font-size: 0.9rem;
color: var(--text-light);
}
.positive {
color: var(--success);
}
.negative {
color: var(--danger);
}
.chart-container {
width: 100%;
height: 300px; /* Altura fija, Chart.js se encarga de la responsividad interna */
}
.data-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.data-table th,
.data-table td {
padding: 0.75rem 1rem;
text-align: left;
border-bottom: 1px solid var(--gray);
}
.data-table th {
background-color: var(--gray-light);
font-weight: 600;
}
.data-table tr:last-child td {
border-bottom: none;
}
.data-table tr:hover {
background-color: var(--gray-light);
}
.badge {
display: inline-block;
padding: 0.25em 0.6em;
font-size: 0.75rem;
font-weight: 600;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: 10px;
}
.badge-success {
background-color: var(--success);
color: var(--light);
}
.badge-warning {
background-color: var(--warning);
color: var(--dark);
}
.badge-danger {
background-color: var(--danger);
color: var(--light);
}
.tabs {
display: flex;
margin-bottom: 1rem;
border-bottom: 1px solid var(--gray);
flex-wrap: wrap; /* Permite que las pestañas se envuelvan */
}
.tab {
padding: 0.75rem 1.5rem;
cursor: pointer;
transition: var(--transition);
border-bottom: 3px solid transparent;
font-weight: 500;
flex-grow: 1; /* Permite que las pestañas llenen el espacio */
text-align: center; /* Centra el texto en las pestañas */
}
.tab.active {
border-bottom-color: var(--primary);
color: var(--primary);
}
.tab:hover {
background-color: var(--gray-light);
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.footer {
background-color: var(--light);
padding: 1rem 1.5rem; /* Ajuste de padding */
text-align: center;
color: var(--text-light);
border-top: 1px solid var(--gray);
font-size: 0.9rem; /* Ajuste de tamaño */
}
.negative {
color: var(--danger);
}
.income-table .income-amount.negative {
color: var(--danger);
}
/* Estilos para tablas en pantallas pequeñas */
.income-table {
display: block;
width: 100%;
overflow-x: auto; /* Permite scroll horizontal en tablas grandes */
-webkit-overflow-scrolling: touch; /* Mejora el scroll en iOS */
}
.income-table .income-row {
display: flex;
flex-direction: row; /* Vuelve a row para pantallas pequeñas */
align-items: center;
padding: 10px;
border-bottom: 1px solid var(--gray);
}
.income-table .income-header {
font-weight: 600;
background-color: var(--gray-light);
}
.income-table .income-category,
.income-table .income-amount {
flex: 1; /* Distribuye el espacio */
text-align: left;
padding: 5px 10px; /* Ajuste de padding */
word-break: break-word; /* Rompe palabras largas */
}
.income-table .income-amount {
text-align: right; /* Alinea los montos a la derecha */
}
/* Estilo personalizado para datos fiscales */
.fiscal-info {
margin-top: 20px;
}
.fiscal-data {
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 15px;
}
.fiscal-item {
display: flex;
justify-content: space-between;
padding: 10px 15px;
background-color: var(--gray-light);
border-radius: 6px;
flex-wrap: wrap; /* Permite que los elementos se envuelvan */
}
.fiscal-item .fiscal-label,
.fiscal-item .fiscal-value {
flex-basis: 50%; /* Intenta que cada uno ocupe la mitad */
padding: 5px 0;
}
.fiscal-item .fiscal-value {
text-align: right; /* Alinea los valores a la derecha */
}
.fiscal-item.highlight {
background-color: rgba(0, 102, 204, 0.1);
border-left: 4px solid var(--primary);
}
.fiscal-label {
font-weight: 500;
}
.fiscal-value {
font-weight: 600;
}
.fiscal-value.positive {
color: var(--success);
}
/* Hide content sections by default */
.content-section {
display: none;
}
/* Show the active content section */
.content-section.active {
display: block;
}
/* Style for report content area */
#report-content {
margin-top: 20px;
}
/* Media Queries para adaptabilidad */
@media (max-width: 768px) {
.header {
flex-direction: column; /* Apila elementos del header en pantallas pequeñas */
align-items: flex-start; /* Alinea elementos a la izquierda */
}
.logo-container, .user-info {
width: 100%; /* Ocupa todo el ancho */
margin-bottom: 0.8rem;
}
.user-info {
justify-content: flex-end; /* Alinea info de usuario a la derecha */
margin-top: -30px; /* Ajusta para superponer con logo */
}
.container {
grid-template-columns: 1fr; /* Apila sidebar y contenido principal */
}
.sidebar {
padding: 1rem;
border-right: none;
border-bottom: 1px solid var(--gray); /* Añade borde inferior */
}
.menu {
display: flex; /* Convierte el menú en flexbox */
overflow-x: auto; /* Permite scroll horizontal si hay muchos elementos */
-webkit-overflow-scrolling: touch;
padding-bottom: 10px; /* Espacio para la barra de scroll */
}
.menu-item {
flex-shrink: 0; /* Evita que los items se encojan */
margin-right: 10px; /* Espacio entre items */
margin-bottom: 0; /* Elimina margen inferior */
font-size: 0.9rem; /* Ajuste de tamaño */
}
/* Ocultar texto del menú en pantallas muy pequeñas si es necesario */
/* @media (max-width: 480px) {
.menu-item span {
display: none;
}
.menu-item i {
margin-right: 0;
}
} */
.main-content {
padding: 1rem;
}
.page-title {
font-size: 1.3rem;
margin-bottom: 1rem;
}
.dashboard-grid {
grid-template-columns: 1fr; /* Apila las tarjetas */
}
.card {
padding: 1rem;
}
.card-title {
font-size: 1rem;
}
.stat-value {
font-size: 1.5rem;
}
.tabs .tab {
padding: 0.5rem 1rem; /* Ajuste de padding */
font-size: 0.9rem; /* Ajuste de tamaño */
}
/* Ajustes específicos para la tabla de ingresos en móvil */
.income-table .income-row {
flex-wrap: wrap; /* Permite que las columnas se envuelvan */
}
.income-table .income-category,
.income-table .income-table .income-amount {
flex-basis: 100%; /* Cada celda ocupa su propia línea */
text-align: left; /* Alinea texto a la izquierda */
padding: 5px 0;
}
.income-table .income-amount {
text-align: left; /* Asegura alineación izquierda para montos en móvil */
font-weight: normal; /* Opcional: reduce peso de fuente en móvil */
margin-top: -5px; /* Ajuste de espacio */
color: var(--text-light); /* Opcional: color diferente para valor */
}
.income-table .income-header .income-amount {
text-align: left; /* Asegura alineación izquierda para encabezados de monto */
font-weight: 600;
color: var(--text);
}
}
</style>
</head>
<body>
<div class="header">
<div class="logo-container">
<div class="logo">
<img src="<https://assets.zyrosite.com/cdn-cgi/image/format=auto,w=646,h=430,fit=crop/mk38oVQoDrivRDKB/logo-defycontmt-mv07K1MpOvig1nJ7.jpg>" alt="Logo">
</div>
<div class="logo-text">Dashboard Fiscal</div>
</div>
<div class="user-info">
<div class="user-name">Rosa Maria Morales Camacho</div>
<div class="user-icon">RM</div>
</div>
</div>
<div class="container">
<div class="sidebar">
<ul class="menu">
<li class="menu-item active" data-section="dashboard">
<i>📊</i> <span>Dashboard</span>
</li>
<li class="menu-item" data-section="ingresos">
<i>💰</i> <span>Ingresos</span>
</li>
<li class="menu-item" data-section="declaraciones">
<i>🧾</i> <span>Declaraciones</span>
</li>
<li class="menu-item" data-section="deducciones">
<i>📝</i> <span>Deducciones</span>
</li>
<li class="menu-item" data-section="reportes">
<i>📋</i> <span>Reportes</span>
</li>
<li class="menu-item" data-section="configuracion">
<i>⚙️</i> <span>Configuración</span>
</li>
</ul>
</div>
<div class="main-content">
<div class="content-section active" id="dashboard-section">
<h1 class="page-title">Resumen Fiscal 2024</h1>
<div class="dashboard-grid">
<div class="card highlight-card">
<div class="card-header">
<div class="card-title">ISR a Favor</div>
<div class="card-icon">💹</div>
</div>
<div class="stat-value">$5,335.00</div>
<div class="stat-label">Ejercicio 2023 (Act. Empresarial)</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">Ingresos Acumulables</div>
<div class="card-icon">💵</div>
</div>
<div class="stat-value">$130,001.00</div>
<div class="stat-label">Total del ejercicio</div>
</div>
<div class="card">
<div class="card-header">
<div class="card-title">ISR Retenido</div>
<div class="card-icon">🔄</div>
</div>
<div class="stat-value">$15,674.00</div>
<div class="stat-label">Retención por sueldos</div>
</div>
</div>
<div class="tabs">
<div class="tab active" data-tab="resumen">Resumen del Cálculo</div>
<div class="tab" data-tab="ingresos-dashboard">Desglose de Ingresos</div>
</div>
<div class="tab-content active" id="resumen">
<div class="card">
<div class="card-header">
<div class="card-title">Cálculo de ISR del Ejercicio 2023 (Actividad Empresarial)</div>
</div>
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">RFC:</div>
<div class="fiscal-value">MOCR800114MR2</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Base gravable:</div>
<div class="fiscal-value">$130,001.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Límite Inferior:</div>
<div class="fiscal-value">$75,985.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Excedente de Límite Inferior:</div>
<div class="fiscal-value">$54,017.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Tasa del ISR 2023:</div>
<div class="fiscal-value">10.88%</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Impuesto Marginal:</div>
<div class="fiscal-value">$5,877.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Cuota Fija:</div>
<div class="fiscal-value">$4,462.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR Tarifa anual:</div>
<div class="fiscal-value">$10,339.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR Retenido por Sueldos:</div>
<div class="fiscal-value">$15,674.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR a Cargo:</div>
<div class="fiscal-value">$0.00</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">ISR a Favor:</div>
<div class="fiscal-value positive">$5,335.00</div>
</div>
</div>
<p style="margin-top: 15px; font-size: 0.9rem; color: var(--text-light);">Nota: Datos de cálculo de ISR del ejercicio 2023 de Actividad Empresarial.</p>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Resumen Anual de Ingresos y Deducciones (2024)</div>
</div>
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">Total Ingresos Gravados:</div>
<div class="fiscal-value">$158,811.56</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Total Ingresos Exentos:</div>
<div class="fiscal-value">$28,154.95</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Total Ingresos:</div>
<div class="fiscal-value">$186,966.51</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Total Deducciones:</div>
<div class="fiscal-value">$82,672.59</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Reintegro de ISR en exceso:</div>
<div class="fiscal-value positive">$484.56</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR Retenido Anual:</div>
<div class="fiscal-value">$15,674.42</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">Ingreso Neto Anual:</div>
<div class="fiscal-value">$104,293.92</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Distribución del ISR</div>
</div>
<div class="chart-container">
<canvas id="isrChart"></canvas>
</div>
</div>
</div>
<div class="tab-content" id="ingresos-dashboard">
<div class="card">
<div class="card-header">
<div class="card-title">Desglose de Ingresos (Datos CFDI)</div>
</div>
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Total Gravado</div>
<div class="income-amount">Total Exento</div>
</div>
<div class="income-row">
<div class="income-category">Sueldos, Salarios, Rayas y Jornales</div>
<div class="income-amount">$131,649.21</div>
<div class="income-amount">$0.00</div>
</div>
<div class="income-row">
<div class="income-category">Gratificación Anual (Aguinaldo)</div>
<div class="income-amount">$2,279.55</div>
<div class="income-amount">$3,257.10</div>
</div>
<div class="income-row">
<div class="income-category">Otros ingresos por salarios</div>
<div class="income-amount">$11,073.42</div>
<div class="income-amount">$1,840.30</div>
</div>
<div class="income-row">
<div class="income-category">Participación de los Trabajadores en las Utilidades PTU</div>
<div class="income-amount">$2,961.29</div>
<div class="income-amount">$1,628.55</div>
</div>
<div class="income-row">
<div class="income-category">Premios por puntualidad</div>
<div class="income-amount">$10,815.04</div>
<div class="income-amount">$1,840.30</div>
</div>
<div class="income-row">
<div class="income-category">Prima vacacional</div>
<div class="income-amount">$32.45</div>
<div class="income-amount">$1,628.55</div>
</div>
<div class="income-row">
<div class="income-category">Vales de despensa</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">$15,436.35</div>
</div>
<div class="income-row">
<div class="income-category">Fondo de Ahorro</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">$2,523.80</div>
</div>
<div class="income-row income-header">
<div class="income-category">TOTAL</div>
<div class="income-amount">$158,811.56</div>
<div class="income-amount">$28,154.95</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Distribución de Ingresos</div>
</div>
<div class="chart-container">
<canvas id="incomesChartDashboard"></canvas>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Deducciones / Pagos (Datos CFDI)</div>
</div>
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Monto</div>
</div>
<div class="income-row">
<div class="income-category">ISR</div>
<div class="income-amount">$15,674.42</div>
</div>
<div class="income-row">
<div class="income-category">Otros</div>
<div class="income-amount">$5,049.14</div>
</div>
<div class="income-row">
<div class="income-category">Pagos distintos a los listados y que no deben considerarse como ingreso por sueldos, salarios o ingresos asimilados.</div>
<div class="income-amount">$1.48</div>
</div>
<div class="income-row">
<div class="income-category">Préstamos provenientes del Fondo Nacional de la Vivienda para los Trabajadores</div>
<div class="income-amount">$58,077.77</div>
</div>
<div class="income-row">
<div class="income-category">Reintegro de ISR pagado en exceso (siempre que no haya sido enterado al SAT).</div>
<div class="income-amount">$484.56</div>
</div>
<div class="income-row">
<div class="income-category">Seguridad social</div>
<div class="income-amount">$3,385.22</div>
</div>
<div class="income-row">
<div class="income-category">Subsidio para el empleo (efectivamente entregado al trabajador).</div>
<div class="income-amount">$0.00</div>
</div>
<div class="income-row income-header">
<div class="income-category">TOTAL DEDUCCIONES</div>
<div class="income-amount">$82,672.59</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Evolución Mensual de Ingresos y Deducciones</div>
</div>
<div class="chart-container">
<canvas id="monthlyBalanceChart"></canvas>
</div>
</div>
</div>
</div>
<div class="content-section" id="ingresos-section">
<h1 class="page-title">Ingresos</h1>
<div class="card">
<div class="card-header">
<div class="card-title">Desglose de Ingresos por Tipo</div>
</div>
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Total Gravado</div>
<div class="income-amount">Total Exento</div>
<div class="income-amount">Total</div>
</div>
<div class="income-row">
<div class="income-category">Sueldos, Salarios, Rayas y Jornales</div>
<div class="income-amount">$131,649.21</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">$131,649.21</div>
</div>
<div class="income-row">
<div class="income-category">Gratificación Anual (Aguinaldo)</div>
<div class="income-amount">$2,279.55</div>
<div class="income-amount">$3,257.10</div>
<div class="income-amount">$5,536.65</div>
</div>
<div class="income-row">
<div class="income-category">Otros ingresos por salarios</div>
<div class="income-amount">$11,073.42</div>
<div class="income-amount">$1,840.30</div>
<div class="income-amount">$12,913.72</div>
</div>
<div class="income-row">
<div class="income-category">Participación de los Trabajadores en las Utilidades PTU</div>
<div class="income-amount">$2,961.29</div>
<div class="income-amount">$1,628.55</div>
<div class="income-amount">$4,589.84</div>
</div>
<div class="income-row">
<div class="income-category">Premios por puntualidad</div>
<div class="income-amount">$10,815.04</div>
<div class="income-amount">$1,840.30</div>
<div class="income-amount">$12,655.34</div>
</div>
<div class="income-row">
<div class="income-category">Prima vacacional</div>
<div class="income-amount">$32.45</div>
<div class="income-amount">$1,628.55</div>
<div class="income-amount">$1,661.00</div>
</div>
<div class="income-row">
<div class="income-category">Vales de despensa</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">$15,436.35</div>
<div class="income-amount">$15,436.35</div>
</div>
<div class="income-row">
<div class="income-category">Fondo de Ahorro</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">$2,523.80</div>
<div class="income-amount">$2,523.80</div>
</div>
<div class="income-row income-header">
<div class="income-category">TOTAL</div>
<div class="income-amount">$158,811.56</div>
<div class="income-amount">$28,154.95</div>
<div class="income-amount">$186,966.51</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Análisis de Ingresos</div>
</div>
<div class="chart-container">
<canvas id="ingresos-chart"></canvas>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Evolución Mensual de Ingresos</div>
</div>
<div class="chart-container">
<canvas id="ingresos-mensuales-chart"></canvas>
</div>
<div style="padding: 20px;">
<p><strong>Nota:</strong> Se observan incrementos significativos en los meses de Mayo y Diciembre. En Mayo se debe principalmente al pago de PTU y en Diciembre al aguinaldo.</p>
</div>
</div>
</div>
<div class="content-section" id="declaraciones-section">
<h1 class="page-title">Declaraciones</h1>
<div class="card">
<div class="card-header">
<div class="card-title">Declaraciones Fiscales</div>
</div>
<div style="padding: 20px;">
<h3>Declaración Anual 2024</h3>
<p style="margin-top: 15px;">Estatus: <span class="badge badge-warning">Pendiente</span></p>
<p>Fecha límite de presentación: 30/04/2025</p>
<p>ISR a favor estimado: $5,335.00</p>
<p>Ingresos acumulables: $130,001.00</p>
<div class="fiscal-data" style="margin-top: 20px;">
<div class="fiscal-item">
<div class="fiscal-label">RFC:</div>
<div class="fiscal-value">MOCR800114MR2</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Nombre:</div>
<div class="fiscal-value">ROSA MARIA MORALES CAMACHO</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Régimen:</div>
<div class="fiscal-value">Sueldos y Salarios y Actividad Empresarial</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Año fiscal:</div>
<div class="fiscal-value">2024</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR Determinado estimado:</div>
<div class="fiscal-value">$10,339.00</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">ISR Retenido:</div>
<div class="fiscal-value">$15,674.00</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">Saldo a favor estimado:</div>
<div class="fiscal-value positive">$5,335.00</div>
</div>
</div>
<button style="background-color: var(--primary); color: white; border: none; padding: 10px 15px; border-radius: 5px; margin-top: 15px; cursor: pointer;">Preparar declaración</button>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Historial de Declaraciones</div>
</div>
<div style="padding: 20px;">
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Año</div>
<div class="income-amount">Ingresos</div>
<div class="income-amount">ISR Determinado</div>
<div class="income-amount">Resultado</div>
</div>
<div class="income-row">
<div class="income-category">2024</div>
<div class="income-amount">$130,001.00</div>
<div class="income-amount">$10,339.00</div>
<div class="income-amount positive">$5,335.00 a favor</div>
</div>
</div>
</div>
</div>
</div>
<div class="content-section" id="deducciones-section">
<h1 class="page-title">Deducciones</h1>
<div class="card">
<div class="card-header">
<div class="card-title">Deducciones / Pagos de Nómina</div>
</div>
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Monto</div>
<div class="income-amount">Porcentaje</div>
</div>
<div class="income-row">
<div class="income-category">ISR</div>
<div class="income-amount">$15,674.42</div>
<div class="income-amount">18.96%</div>
</div>
<div class="income-row">
<div class="income-category">Otros</div>
<div class="income-amount">$5,049.14</div>
<div class="income-amount">6.11%</div>
</div>
<div class="income-row">
<div class="income-category">Pagos distintos a los listados y que no deben considerarse como ingreso por sueldos, salarios o ingresos asimilados.</div>
<div class="income-amount">$1.48</div>
<div class="income-amount">0.00%</div>
</div>
<div class="income-row">
<div class="income-category">Préstamos provenientes del Fondo Nacional de la Vivienda para los Trabajadores</div>
<div class="income-amount">$58,077.77</div>
<div class="income-amount">70.25%</div>
</div>
<div class="income-row">
<div class="income-category">Reintegro de ISR pagado en exceso (siempre que no haya sido enterado al SAT).</div>
<div class="income-amount">$484.56</div>
<div class="income-amount">0.59%</div>
</div>
<div class="income-row">
<div class="income-category">Seguridad social</div>
<div class="income-amount">$3,385.22</div>
<div class="income-amount">4.10%</div>
</div>
<div class="income-row">
<div class="income-category">Subsidio para el empleo (efectivamente entregado al trabajador).</div>
<div class="income-amount">$0.00</div>
<div class="income-amount">0.00%</div>
</div>
<div class="income-row income-header">
<div class="income-category">TOTAL DEDUCCIONES</div>
<div class="income-amount">$82,672.59</div>
<div class="income-amount">100.00%</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Límite de Deducciones Personales (2024)</div>
</div>
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">Ingreso Anual:</div>
<div class="fiscal-value">$186,065.91</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">15% del Ingreso:</div>
<div class="fiscal-value">$27,909.89</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">5 UMA anuales (2024):</div>
<div class="fiscal-value">$198,031.80</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">Límite de deducción permitido:</div>
<div class="fiscal-value">$27,909.89</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Deducciones Personales Aplicables</div>
</div>
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">Total de deducciones personales:</div>
<div class="fiscal-value">$29,704.77</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">Deducción Aplicable (menor entre total y límite permitido):</div>
<div class="fiscal-value">$27,909.89</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">TOTAL A DEDUCIR EN EL AÑO:</div>
<div class="fiscal-value">$27,909.89</div>
</div>
</div>
<p style="margin-top: 15px; font-size: 0.9rem; color: var(--text-light);">Según el Artículo 151 LISR 2024, las deducciones personales no excederán de la cantidad que resulte menor entre cinco veces la UMA anual y el 15% del total de los ingresos del contribuyente.</p>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Distribución de Deducciones</div>
</div>
<div class="chart-container">
<canvas id="deducciones-chart"></canvas>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Evolución Mensual de Deducciones</div>
</div>
<div class="chart-container">
<canvas id="deducciones-mensuales-chart"></canvas>
</div>
<div style="padding: 20px;">
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">Promedio Mensual de Deducciones:</div>
<div class="fiscal-value">$6,889.38</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Mayor Deducción Mensual:</div>
<div class="fiscal-value">Datos de ejemplo (Abril)</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Menor Deducción Mensual:</div>
<div class="fiscal-value">Datos de ejemplo (Agosto)</div>
</div>
</div>
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Evolución de ISR Retenido</div>
</div>
<div class="chart-container">
<canvas id="isr-mensual-chart"></canvas>
</div>
<div style="padding: 20px;">
<p><strong>Nota:</strong> La retención de ISR muestra variaciones en los meses de abril, mayo, julio, septiembre y diciembre, debido a cambios en los ingresos gravados durante esos periodos.</p>
</div>
</div>
</div>
<div class="content-section" id="reportes-section">
<h1 class="page-title">Reportes</h1>
<div class="card">
<div class="card-header">
<div class="card-title">Reportes Disponibles</div>
</div>
<div style="padding: 20px;">
<div style="display: flex; gap: 15px; flex-wrap: wrap;">
<div class="report-item" data-report="annual-income" style="background-color: var(--gray-light); padding: 20px; border-radius: 8px; width: 200px; cursor: pointer;">
<div style="font-size: 24px; margin-bottom: 10px;">📄</div>
<div>Reporte Anual de Ingresos</div>
</div>
<div class="report-item" data-report="deductions-by-category" style="background-color: var(--gray-light); padding: 20px; border-radius: 8px; width: 200px; cursor: pointer;">
<div style="font-size: 24px; margin-bottom: 10px;">📊</div>
<div>Reporte de Deducciones por Categoría</div>
</div>
<div class="report-item" data-report="monthly-evolution" style="background-color: var(--gray-light); padding: 20px; border-radius: 8px; width: 200px; cursor: pointer;">
<div style="font-size: 24px; margin-bottom: 10px;">📈</div>
<div>Evolución Mensual Fiscal</div>
</div>
</div>
<div id="report-content">
</div>
</div>
</div>
</div>
<div class="content-section" id="configuracion-section">
<h1 class="page-title">Configuración</h1>
<div class="card">
<div class="card-header">
<div class="card-title">Ajustes de la Cuenta</div>
</div>
<div style="padding: 20px;">
<p>Aquí podrás gestionar la configuración de tu perfil y preferencias.</p>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
© 2025 Dashboard Fiscal | Desarrollado por un Profesional Contable
</div>
<script>
let payrollData = []; // Variable para almacenar los datos de nómina
// Script para la navegación del sidebar
document.querySelectorAll('.menu-item').forEach(item => {
item.addEventListener('click', () => {
const sectionId = item.getAttribute('data-section') + '-section';
// Remove active class from all menu items and content sections
document.querySelectorAll('.menu-item').forEach(i => i.classList.remove('active'));
document.querySelectorAll('.content-section').forEach(s => s.classList.remove('active'));
// Add active class to the clicked menu item and corresponding content section
item.classList.add('active');
document.getElementById(sectionId).classList.add('active');
// Re-initialize charts when the section becomes active
if (sectionId === 'dashboard-section') {
initializeDashboardCharts();
} else if (sectionId === 'ingresos-section') {
initializeIngresosCharts();
} else if (sectionId === 'deducciones-section') {
initializeDeduccionesCharts();
} else if (sectionId === 'reportes-section') {
// Clear previous report content when navigating to reports
document.getElementById('report-content').innerHTML = '';
}
});
});
// Script para el cambio de pestañas dentro de las secciones (ej. Dashboard)
document.querySelectorAll('.tabs .tab').forEach(tab => {
tab.addEventListener('click', () => {
const tabId = tab.getAttribute('data-tab');
const parentTabsContainer = tab.closest('.tabs');
const parentContentSection = tab.closest('.content-section');
// Desactivar todas las pestañas dentro del mismo contenedor de pestañas
parentTabsContainer.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
// Desactivar todos los contenidos de pestaña dentro de la misma sección de contenido
parentContentSection.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
// Activar la pestaña seleccionada
tab.classList.add('active');
document.getElementById(tabId).classList.add('active');
// Re-initialize charts when the tab becomes active
if (tabId === 'resumen') {
initializeDashboardCharts(); // Re-initialize dashboard charts if needed
} else if (tabId === 'ingresos-dashboard') {
initializeIncomesChartDashboard();
}
});
});
// Función para parsear CSV
function parseCSV(csvText) {
const lines = csvText.split('\\n');
const headers = lines[0].split(',');
const data = [];
for (let i = 1; i < lines.length; i++) {
const values = lines[i].split(',');
if (values.length === headers.length) {
const row = {};
for (let j = 0; j < headers.length; j++) {
row[headers[j].trim()] = values[j].trim();
}
data.push(row);
}
}
return data;
}
// Función para cargar datos de nómina
async function loadPayrollData() {
// Replace with the actual path or method to access the uploaded CSV
const csvFilePath = '2024.xlsx - BDD NOMINAS.csv'; // Assuming the file is accessible by this name
try {
const response = await fetch(csvFilePath);
const csvText = await response.text();
payrollData = parseCSV(csvText);
console.log('Datos de nómina cargados:', payrollData);
// Filter data for 2024 if Año Comprobante column exists and is needed
payrollData = payrollData.filter(row => row['Año Comprobante'] === '2024');
console.log('Datos de nómina 2024 filtrados:', payrollData);
} catch (error) {
console.error('Error al cargar los datos de nómina:', error);
document.getElementById('report-content').innerHTML = '<p style="color: red;">Error al cargar los datos de nómina. Asegúrate de que el archivo "2024.xlsx - BDD NOMINAS.csv" esté disponible.</p>';
}
}
// --- Funciones para generar reportes ---
function generateAnnualIncomeReport(data) {
// Use the hardcoded data from the third image for the annual report
const incomeData = [
{ concepto: 'Sueldos, Salarios Rayas y Jornales', gravado: 131649.21, exento: 0.00 },
{ concepto: 'Gratificación Anual (Aguinaldo)', gravado: 2279.55, exento: 3257.10 },
{ concepto: 'Otros ingresos por salarios', gravado: 11073.42, exento: 1840.30 },
{ concepto: 'Participación de los Trabajadores en las Utilidades PTU', gravado: 2961.29, exento: 1628.55 },
{ concepto: 'Premios por puntualidad', gravado: 10815.04, exento: 1840.30 },
{ concepto: 'Prima vacacional', gravado: 32.45, exento: 1628.55 },
{ concepto: 'Vales de despensa', gravado: 0.00, exento: 15436.35 },
{ concepto: 'Fondo de Ahorro', gravado: 0.00, exento: 2523.80 }
];
let totalGravado = 0;
let totalExento = 0;
incomeData.forEach(item => {
totalGravado += item.gravado;
totalExento += item.exento;
});
const formattedTotalGravado = new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(totalGravado);
const formattedTotalExento = new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(totalExento);
const formattedTotalIngresos = new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(totalGravado + totalExento);
let html = `
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Reporte Anual de Ingresos (2024)</div>
</div>
<div class="fiscal-data">
<div class="fiscal-item">
<div class="fiscal-label">Total Ingresos Gravados:</div>
<div class="fiscal-value">${formattedTotalGravado}</div>
</div>
<div class="fiscal-item">
<div class="fiscal-label">Total Ingresos Exentos:</div>
<div class="fiscal-value">${formattedTotalExento}</div>
</div>
<div class="fiscal-item highlight">
<div class="fiscal-label">Total Ingresos Anual:</div>
<div class="fiscal-value">${formattedTotalIngresos}</div>
</div>
</div>
<div style="padding: 20px;">
<h4>Desglose por Concepto</h4>
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Gravado</div>
<div class="income-amount">Exento</div>
</div>
`;
incomeData.forEach(item => {
html += `
<div class="income-row">
<div class="income-category">${item.concepto}</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(item.gravado)}</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(item.exento)}</div>
</div>
`;
});
html += `
</div>
</div>
</div>
`;
return html;
}
function generateDeductionsByCategoryReport(data) {
// Use the hardcoded data from the third image for the deductions report
const deductionsData = [
{ concepto: 'ISR', monto: 15674.42 },
{ concepto: 'Otros', monto: 5049.14 },
{ concepto: 'Pagos distintos a los listados y que no deben considerarse como ingreso por sueldos, salarios o ingresos asimilados.', monto: 1.48 },
{ concepto: 'Préstamos provenientes del Fondo Nacional de la Vivienda para los Trabajadores', monto: 58077.77 },
{ concepto: 'Reintegro de ISR pagado en exceso (siempre que no haya sido enterado al SAT).', monto: 484.56 },
{ concepto: 'Seguridad social', monto: 3385.22 },
{ concepto: 'Subsidio para el empleo (efectivamente entregado al trabajador).', monto: 0.00 }
];
let html = `
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Reporte de Deducciones por Categoría (2024)</div>
</div>
<div style="padding: 20px;">
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Concepto</div>
<div class="income-amount">Monto</div>
</div>
`;
let totalDeducciones = 0;
deductionsData.forEach(item => {
totalDeducciones += item.monto;
html += `
<div class="income-row">
<div class="income-category">${item.concepto}</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(item.monto)}</div>
</div>
`;
});
html += `
<div class="income-row income-header">
<div class="income-category">TOTAL DEDUCCIONES</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(totalDeducciones)}</div>
</div>
`;
html += `
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Distribución de Deducciones</div>
</div>
<div class="chart-container">
<canvas id="deductionsByCategoryChart"></canvas>
</div>
</div>
</div>
`;
// Data for the chart
const chartLabels = deductionsData.map(item => item.concepto);
const chartData = deductionsData.map(item => item.monto);
// Add script to render the chart after the HTML is in the DOM
setTimeout(() => {
const ctx = document.getElementById('deductionsByCategoryChart').getContext('2d');
if (window.deductionsByCategoryChartInstance) {
window.deductionsByCategoryChartInstance.destroy();
}
window.deductionsByCategoryChartInstance = new Chart(ctx, {
type: 'pie',
data: {
labels: chartLabels,
datasets: [{
data: chartData,
backgroundColor: [
'#0066cc', '#00a1e0', '#ffc107', '#28a745', '#dc3545', '#6f42c1', '#fd7e14', '#20c997'
],
borderColor: '#ffffff',
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
font: {
size: 12
},
padding: 20
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed);
}
return label;
}
}
}
}
}
});
}, 0); // Use setTimeout to ensure the canvas element is in the DOM
return html;
}
function generateMonthlyEvolutionReport(data) {
// This report requires monthly data, which is not available in the provided images.
// Using placeholder data or data from the original CSV if available.
const monthlyData = {};
const months = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
// Using placeholder data for now
months.forEach((month, index) => {
monthlyData[index + 1] = { ingresos: Math.random() * 20000 + 10000, deducciones: Math.random() * 8000 + 4000 };
});
let html = `
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Evolución Mensual Fiscal (2024)</div>
</div>
<div style="padding: 20px;">
<div class="income-table">
<div class="income-row income-header">
<div class="income-category">Mes</div>
<div class="income-amount">Ingresos Totales</div>
<div class="income-amount">Deducciones Totales</div>
<div class="income-amount">Saldo Neto</div>
</div>
`;
const monthlyIncomeData = [];
const monthlyDeductionsData = [];
const monthlyNetBalanceData = [];
for (let i = 1; i <= 12; i++) {
const ingresos = monthlyData[i].ingresos;
const deducciones = monthlyData[i].deducciones;
const saldoNeto = ingresos - deducciones;
monthlyIncomeData.push(ingresos);
monthlyDeductionsData.push(deducciones);
monthlyNetBalanceData.push(saldoNeto);
html += `
<div class="income-row">
<div class="income-category">${months[i - 1]}</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(ingresos)}</div>
<div class="income-amount">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(deducciones)}</div>
<div class="income-amount ${saldoNeto >= 0 ? 'positive' : 'negative'}">${new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(saldoNeto)}</div>
</div>
`;
}
html += `
</div>
</div>
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<div class="card-title">Gráfica de Evolución Mensual</div>
</div>
<div class="chart-container">
<canvas id="monthlyEvolutionChart"></canvas>
</div>
</div>
</div>
`;
// Add script to render the chart after the HTML is in the DOM
setTimeout(() => {
const ctx = document.getElementById('monthlyEvolutionChart').getContext('2d');
if (window.monthlyEvolutionChartInstance) {
window.monthlyEvolutionChartInstance.destroy();
}
window.monthlyEvolutionChartInstance = new Chart(ctx, {
type: 'line',
data: {
labels: months,
datasets: [
{
label: 'Ingresos Totales',
data: monthlyIncomeData,
borderColor: '#0066cc',
tension: 0.1,
fill: false
},
{
label: 'Deducciones Totales',
data: monthlyDeductionsData,
borderColor: '#dc3545',
tension: 0.1,
fill: false
},
{
label: 'Saldo Neto',
data: monthlyNetBalanceData,
borderColor: '#28a745',
tension: 0.1,
fill: false
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
}, 0); // Use setTimeout to ensure the canvas element is in the DOM
return html;
}
// Event listeners for report items
document.querySelectorAll('.report-item').forEach(item => {
item.addEventListener('click', async () => {
const reportType = item.getAttribute('data-report');
const reportContentArea = document.getElementById('report-content');
// Clear previous report content
reportContentArea.innerHTML = 'Cargando reporte...';
// Load data if not already loaded (only needed for monthly evolution if using CSV)
// if (payrollData.length === 0 && reportType === 'monthly-evolution') {
// await loadPayrollData();
// }
// Generate and display the selected report
let reportHtml = '';
// For annual income and deductions by category, use the hardcoded data from the third image
if (reportType === 'annual-income') {
reportHtml = generateAnnualIncomeReport(); // No data argument needed as it uses hardcoded data
} else if (reportType === 'deductions-by-category') {
reportHtml = generateDeductionsByCategoryReport(); // No data argument needed as it uses hardcoded data
} else if (reportType === 'monthly-evolution') {
// For monthly evolution, use payrollData if loaded, otherwise indicate data is missing
if (payrollData.length > 0) {
reportHtml = generateMonthlyEvolutionReport(payrollData);
} else {
reportHtml = '<p style="color: red;">Datos mensuales no disponibles para este reporte.</p>';
}
} else {
reportHtml = '<p>Reporte no encontrado.</p>';
}
reportContentArea.innerHTML = reportHtml;
});
});
// Initialize charts for the Dashboard section
function initializeDashboardCharts() {
// Check if charts already exist to prevent re-initialization issues
if (window.isrChartInstance) {
window.isrChartInstance.destroy();
}
if (window.incomesChartDashboardInstance) {
window.incomesChartDashboardInstance.destroy();
}
if (window.monthlyBalanceChartInstance) {
window.monthlyBalanceChartInstance.destroy();
}
// Gráfica de Distribución del ISR (using data from the first image)
const isrCtx = document.getElementById('isrChart').getContext('2d');
window.isrChartInstance = new Chart(isrCtx, {
type: 'pie',
data: {
labels: ['ISR Tarifa anual', 'ISR a Favor'],
datasets: [{
data: [10339, 5335],
backgroundColor: [
'#0066cc',
'#28a745'
],
borderColor: [
'#ffffff',
'#ffffff'
],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
font: {
size: 12
},
padding: 20
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed);
}
return label;
}
}
}
}
}
});
// Gráfica de Distribución de Ingresos en Dashboard Tab (using data from the third image)
const incomesDashboardCtx = document.getElementById('incomesChartDashboard').getContext('2d');
window.incomesChartDashboardInstance = new Chart(incomesDashboardCtx, {
type: 'bar',
data: {
labels: ['Sueldos', 'Aguinaldo', 'Otros ingresos', 'PTU', 'Premios', 'Prima', 'Vales', 'Fondo de Ahorro'],
datasets: [{
label: 'Gravado',
data: [131649.21, 2279.55, 11073.42, 2961.29, 10815.04, 32.45, 0.00, 0.00],
backgroundColor: '#0066cc',
borderColor: '#0052a3',
borderWidth: 1
}, {
label: 'Exento',
data: [0.00, 3257.10, 1840.30, 1628.55, 1840.30, 1628.55, 15436.35, 2523.80],
backgroundColor: '#00a1e0',
borderColor: '#0081b3',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
// Gráfica de Evolución Mensual de Ingresos y Deducciones en Dashboard Tab (using placeholder data)
const monthlyBalanceCtx = document.getElementById('monthlyBalanceChart').getContext('2d');
window.monthlyBalanceChartInstance = new Chart(monthlyBalanceCtx, {
type: 'line',
data: {
labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
datasets: [{
label: 'Ingresos Netos', // Assuming this represents net income
data: [8000, 8500, 8200, 9000, 12000, 8800, 9500, 9200, 9800, 9300, 10000, 15000], // Placeholder data
borderColor: '#28a745',
tension: 0.1,
fill: false
},
{
label: 'Deducciones Totales',
data: [6000, 6200, 6100, 7000, 6500, 6300, 6800, 5900, 6600, 6400, 6700, 7500], // Placeholder data
borderColor: '#dc3545',
tension: 0.1,
fill: false
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
}
}
}
}
}
});
}
// Initialize charts for the Ingresos section (using data from the third image)
function initializeIngresosCharts() {
// Check if charts already exist to prevent re-initialization issues
if (window.ingresosChartInstance) {
window.ingresosChartInstance.destroy();
}
if (window.ingresosMensualesChartInstance) {
window.ingresosMensualesChartInstance.destroy();
}
const incomeData = [
{ concepto: 'Sueldos, Salarios Rayas y Jornales', total: 131649.21 },
{ concepto: 'Gratificación Anual (Aguinaldo)', total: 5536.65 },
{ concepto: 'Otros ingresos por salarios', total: 12913.72 },
{ concepto: 'Participación de los Trabajadores en las Utilidades PTU', total: 4589.84 },
{ concepto: 'Premios por puntualidad', total: 12655.34 },
{ concepto: 'Prima vacacional', total: 1661.00 },
{ concepto: 'Vales de despensa', total: 15436.35 },
{ concepto: 'Fondo de Ahorro', total: 2523.80 }
];
// Gráfica de Análisis de Ingresos
const ingresosCtx = document.getElementById('ingresos-chart').getContext('2d');
window.ingresosChartInstance = new Chart(ingresosCtx, {
type: 'bar',
data: {
labels: incomeData.map(item => item.concepto),
datasets: [{
label: 'Total Ingresos',
data: incomeData.map(item => item.total),
backgroundColor: [
'#0066cc', '#00a1e0', '#ffc107', '#28a745', '#dc3545', '#6f42c1', '#fd7e14', '#20c997'
],
borderColor: [
'#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
// Gráfica de Evolución Mensual de Ingresos (using placeholder data)
const ingresosMensualesCtx = document.getElementById('ingresos-mensuales-chart').getContext('2d');
window.ingresosMensualesChartInstance = new Chart(ingualesMensualesCtx, {
type: 'line',
data: {
labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
datasets: [{
label: 'Total Ingresos',
data: [15000, 14500, 14800, 15500, 20000, 15200, 16000, 15800, 16500, 16200, 17000, 22000], // Placeholder data
borderColor: '#0066cc',
tension: 0.1,
fill: false
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
}
// Initialize charts for the Deducciones section (using data from the third image for distribution, placeholder for monthly)
function initializeDeduccionesCharts() {
// Check if charts already exist to prevent re-initialization issues
if (window.deduccionesChartInstance) {
window.deduccionesChartInstance.destroy();
}
if (window.deduccionesMensualesChartInstance) {
window.deduccionesMensualesChartInstance.destroy();
}
if (window.isrMensualChartInstance) {
window.isrMensualChartInstance.destroy();
}
const deductionsData = [
{ concepto: 'ISR', monto: 15674.42 },
{ concepto: 'Otros', monto: 5049.14 },
{ concepto: 'Pagos distintos a los listados y que no deben considerarse como ingreso por sueldos, salarios o ingresos asimilados.', monto: 1.48 },
{ concepto: 'Préstamos provenientes del Fondo Nacional de la Vivienda para los Trabajadores', monto: 58077.77 },
{ concepto: 'Reintegro de ISR pagado en exceso (siempre que no haya sido enterado al SAT).', monto: 484.56 },
{ concepto: 'Seguridad social', monto: 3385.22 },
{ concepto: 'Subsidio para el empleo (efectivamente entregado al trabajador).', monto: 0.00 }
];
const totalDeducciones = deductionsData.reduce((sum, item) => sum + item.monto, 0);
// Gráfica de Distribución de Deducciones
const deduccionesCtx = document.getElementById('deducciones-chart').getContext('2d');
window.deduccionesChartInstance = new Chart(deduccionesCtx, {
type: 'pie',
data: {
labels: deductionsData.map(item => item.concepto),
datasets: [{
data: deductionsData.map(item => item.monto),
backgroundColor: [
'#0066cc', '#00a1e0', '#ffc107', '#28a745', '#dc3545', '#6f42c1', '#fd7e14', '#20c997'
],
borderColor: [
'#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff', '#ffffff'
],
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
font: {
size: 12
},
padding: 20
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed);
}
return label;
}
}
}
}
}
});
// Gráfica de Evolución Mensual de Deducciones (using placeholder data)
const deduccionesMensualesCtx = document.getElementById('deducciones-mensuales-chart').getContext('2d');
window.deduccionesMensualesChartInstance = new Chart(deduccionesMensualesCtx, {
type: 'line',
data: {
labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
datasets: [{
label: 'Total Deducciones',
data: [6500, 6300, 6400, 7594.64, 6800, 6600, 7000, 5917.93, 7100, 6900, 7200, 7300], // Placeholder data
borderColor: '#dc3545',
tension: 0.1,
fill: false
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
// Gráfica de Evolución de ISR Retenido (using placeholder data)
const isrMensualCtx = document.getElementById('isr-mensual-chart').getContext('2d');
window.isrMensualChartInstance = new Chart(isrMensualCtx, {
type: 'line',
data: {
labels: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],
datasets: [{
label: 'ISR Retenido',
data: [900, 850, 880, 1000, 1200, 950, 1100, 920, 1050, 980, 1020, 1150], // Placeholder data
borderColor: '#ffc107',
tension: 0.1,
fill: false
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return '$' + value.toLocaleString('es-MX');
}
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }).format(context.parsed.y);
}
return label;
}
}
}
}
}
});
}
// Initialize the dashboard section and its charts on page load
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('dashboard-section').classList.add('active');
initializeDashboardCharts();
// Load payroll data when the page loads
loadPayrollData(); // Keep loading CSV data for monthly evolution report placeholder
});
</script>
</body>
</html>