'use client'; import { useState } from 'react'; import { Header } from '@/components/layouts/header'; import { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@horux/shared-ui'; import { KpiCard, PeriodSelector, RegimenSelector } from '@horux/shared-ui'; import { useIvaMensual, useIsrMensual, useResumenIva, useResumenIsr, useCoeficiente } from '@/lib/hooks/use-impuestos'; import { setCoeficiente as setCoeficienteApi } from '@/lib/api/impuestos'; import { useQueryClient } from '@tanstack/react-query'; import { useRegimenesDelPeriodo } from '@/lib/hooks/use-dashboard'; import { Calculator, TrendingUp, TrendingDown, Receipt, Settings, Wallet, CheckSquare, Download } from 'lucide-react'; import { cn } from '@horux/shared-ui'; import { FiscalDisclaimer } from '@/components/fiscal-disclaimer'; import { exportToExcel } from '@/lib/export-excel'; import { ActivosFijosTab } from '@/components/impuestos/activos-fijos-tab'; const meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic']; function getMonthRange(year: number, month: number) { const start = `${year}-${String(month).padStart(2, '0')}-01`; const lastDay = new Date(year, month, 0).getDate(); const end = `${year}-${String(month).padStart(2, '0')}-${String(lastDay).padStart(2, '0')}`; return { start, end }; } export default function ImpuestosPage() { const now = new Date(); const defaultRange = getMonthRange(now.getFullYear(), now.getMonth() + 1); const [fechaInicio, setFechaInicio] = useState(defaultRange.start); const [fechaFin, setFechaFin] = useState(defaultRange.end); const [activeTab, setActiveTab] = useState<'iva' | 'isr' | 'activos-fijos'>('iva'); const [regimenSeleccionado, setRegimenSeleccionado] = useState(null); const [conciliacion, setConciliacion] = useState(false); const año = new Date(fechaInicio + 'T00:00:00').getFullYear(); const mes = new Date(fechaInicio + 'T00:00:00').getMonth() + 1; const queryClient = useQueryClient(); const [coefInput, setCoefInput] = useState(''); const [savingCoef, setSavingCoef] = useState(false); const { data: ivaMensual, isLoading: ivaLoading } = useIvaMensual(año, conciliacion); const { data: isrMensual, isLoading: isrLoading } = useIsrMensual(año, conciliacion, regimenSeleccionado); const { data: resumenIva } = useResumenIva(fechaInicio, fechaFin, conciliacion); const { data: resumenIsr } = useResumenIsr(fechaInicio, fechaFin, conciliacion); const { data: coefData } = useCoeficiente(año); const { data: regimenesPeriodo, isLoading: regimenesLoading } = useRegimenesDelPeriodo(fechaInicio, fechaFin, conciliacion); const regimenesDisponibles = regimenesPeriodo || []; if (regimenSeleccionado && regimenesDisponibles.length > 0 && !regimenesDisponibles.find(r => r.clave === regimenSeleccionado)) { setRegimenSeleccionado(null); } const formatCurrency = (value: number) => new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN', minimumFractionDigits: 0, }).format(value); const drillUrl = (titulo: string, filters: Record) => { const p = new URLSearchParams({ titulo, fechaInicio, fechaFin, status: 'vigente', ...filters }); if (regimenSeleccionado) { if (filters.type === 'EMITIDO') p.set('regimenEmisor', regimenSeleccionado); if (filters.type === 'RECIBIDO') p.set('regimenReceptor', regimenSeleccionado); } return `/drill-down?${p}`; }; return ( <>
{ setFechaInicio(fi); setFechaFin(ff); }} />
{/* Filtros */}
{activeTab === 'iva' && ( <> {/* IVA KPIs */}
r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.trasladado || 0 } icon={} subtitle="Cobrado a clientes" href={drillUrl('IVA Trasladado - CFDIs Emitidos', { bucket: 'causado' })} /> r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.acreditable || 0 } icon={} subtitle="Pagado a proveedores" href={drillUrl('IVA Acreditable - CFDIs Recibidos', { bucket: 'acreditable' })} /> {(() => { const val = regimenSeleccionado ? resumenIva?.retenidoPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.retenido || 0; return ( } trend={val > 0 ? 'up' : val < 0 ? 'down' : 'neutral'} trendValue={val > 0 ? 'A favor' : val < 0 ? 'En contra' : 'Neutro'} /> ); })()} {(() => { const t = regimenSeleccionado ? resumenIva?.trasladadoPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.trasladado || 0; const a = regimenSeleccionado ? resumenIva?.acreditablePorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.acreditable || 0; const ret = regimenSeleccionado ? resumenIva?.retenidoPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIva?.retenido || 0; const res = t - a - ret; return ( } trend={res > 0 ? 'up' : res < 0 ? 'down' : 'neutral'} trendValue={res > 0 ? 'Por pagar' : res < 0 ? 'A favor' : 'Neutro'} /> ); })()} } trend={(resumenIva?.acumuladoAnual || 0) < 0 ? 'up' : 'neutral'} trendValue={(resumenIva?.acumuladoAnual || 0) < 0 ? 'Saldo a favor' : ''} />
{/* IVA Mensual Table */} Histórico IVA {año} {ivaMensual && ivaMensual.length > 0 && ( )} {ivaLoading ? (
Cargando...
) : (
{ivaMensual?.map((row) => ( ))} {(!ivaMensual || ivaMensual.length === 0) && ( )}
Mes Trasladado Acreditable Retenido Resultado Acumulado Estado
{meses[row.mes - 1]} {formatCurrency(row.ivaTrasladado)} {formatCurrency(row.ivaAcreditable)} {formatCurrency(row.ivaRetenido)} 0 ? 'text-destructive' : 'text-success' }`} > {formatCurrency(row.resultado)} 0 ? 'text-destructive' : 'text-success' }`} > {formatCurrency(row.acumulado)} {row.estado === 'declarado' ? 'Declarado' : 'Pendiente'}
No hay registros de IVA para este año
)}
)} {activeTab === 'isr' && ( <> {/* ISR KPIs */} {(() => { const bg = regimenSeleccionado ? resumenIsr?.baseGravablePorRegimen?.find(r => r.regimenClave === regimenSeleccionado) : null; const showUtilidad = true; const ingSel = regimenSeleccionado ? resumenIsr?.ingresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIsr?.ingresosAcumulados || 0; const dedSel = regimenSeleccionado ? resumenIsr?.deduccionesPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIsr?.deducciones || 0; // ISR a pagar filtered by regime const bgSelForKpi = regimenSeleccionado ? resumenIsr?.baseGravablePorRegimen?.find(r => r.regimenClave === regimenSeleccionado) : null; const isrCausadoSel = regimenSeleccionado ? (bgSelForKpi?.isrCausado || 0) : resumenIsr?.isrCausado || 0; const isrRetenidoSel = regimenSeleccionado ? 0 : resumenIsr?.isrRetenido || 0; const isrAPagarSel = Math.max(0, isrCausadoSel - isrRetenidoSel); return (
} href={drillUrl('Ingresos ISR - CFDIs Emitidos', { bucket: 'ingresos' })} /> } href={drillUrl('Deducciones - CFDIs Recibidos', { bucket: 'gastos' })} /> } subtitle={bg ? (bg.formula === 'ingresos-deducciones' ? 'Ingresos - Deducciones' : 'Solo ingresos') : undefined} /> } trend={isrAPagarSel > 0 ? 'up' : 'neutral'} /> } trend={(ingSel - dedSel) > 0 ? 'up' : 'down'} subtitle="Ingresos - Deducciones" />
); })()} {/* ISR Info + Coeficiente */} {(() => { // Regímenes PF no usan coeficiente de utilidad const REGIMENES_PF = ['605', '606', '612', '621', '625']; const isResicoPF = regimenSeleccionado === '626'; // RESICO PF also doesn't use coeficiente const showCoeficiente = !regimenSeleccionado || (!REGIMENES_PF.includes(regimenSeleccionado) && !isResicoPF); return (
Calculo de ISR Acumulado {(() => { const ing = regimenSeleccionado ? resumenIsr?.ingresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIsr?.ingresosAcumulados || 0; const ded = regimenSeleccionado ? resumenIsr?.deduccionesPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0 : resumenIsr?.deducciones || 0; const bg = regimenSeleccionado ? resumenIsr?.baseGravablePorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.baseGravable || 0 : resumenIsr?.baseGravable || 0; const bgRegimen = regimenSeleccionado ? resumenIsr?.baseGravablePorRegimen?.find(r => r.regimenClave === regimenSeleccionado) : null; const causado = regimenSeleccionado ? (bgRegimen?.isrCausado || 0) : resumenIsr?.isrCausado || 0; const retenido = resumenIsr?.isrRetenido || 0; const aPagar = Math.max(0, causado - (regimenSeleccionado ? 0 : retenido)); return (
Ingresos acumulados {formatCurrency(ing)}
(-) Deducciones autorizadas {formatCurrency(ded)}
(=) Base gravable {formatCurrency(bg)}
ISR causado {formatCurrency(causado)}
(-) ISR retenido {formatCurrency(regimenSeleccionado ? 0 : retenido)}
ISR a pagar {formatCurrency(aPagar)}
); })()}
{showCoeficiente && ( Coeficiente de Utilidad {año}

Se utiliza para calcular el ISR de regimenes como General de Ley (601) y otros.

{coefData?.coeficiente !== null && coefData?.coeficiente !== undefined ? (

{coefData.coeficiente}

) : (

No configurado

)}
setCoefInput(e.target.value)} className="h-9" />

Este valor se obtiene de la declaracion anual del ejercicio anterior. No se sobrescribe entre años.

)}
); })()} {/* ISR Monthly Table */} Histórico ISR {año} {isrMensual && isrMensual.length > 0 && ( )} {isrLoading ? (
Cargando...
) : (
{isrMensual?.map((row) => ( ))} {(!isrMensual || isrMensual.length === 0) && ( )} {isrMensual && isrMensual.length > 0 && ( )}
Mes Ingresos Deducciones Base Gravable
{meses[row.mes - 1]} {formatCurrency(row.ingresosAcumulados)} {formatCurrency(row.deducciones)} 0 ? 'text-destructive' : 'text-success'}`}> {formatCurrency(row.baseGravable)}
No hay registros de ISR para este año
Total {formatCurrency(isrMensual.reduce((s, r) => s + r.ingresosAcumulados, 0))} {formatCurrency(isrMensual.reduce((s, r) => s + r.deducciones, 0))} {formatCurrency(isrMensual.reduce((s, r) => s + r.baseGravable, 0))}
)}
)} {activeTab === 'activos-fijos' && ( )}
); }