- Extiende KpiData con ncsEmitidas, ncsEmitidasPorRegimen, ncsRecibidas y ncsRecibidasPorRegimen. - En getKpis se reutilizan calcularNcsEmitidasPorRegimen y calcularNcsRecibidasPorRegimen en paralelo. - En el dashboard se agregan dos KpiCard y su desglose por régimen.
484 lines
21 KiB
TypeScript
484 lines
21 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { Header } from '@/components/layouts/header';
|
|
import { KpiCard } from '@horux/shared-ui';
|
|
import { BarChart } from '@/components/charts/bar-chart';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@horux/shared-ui';
|
|
import { PeriodSelector, RegimenSelector } from '@horux/shared-ui';
|
|
import { useKpis, useIngresosEgresos, useAlertas, useRegimenesDelPeriodo } from '@/lib/hooks/use-dashboard';
|
|
import { useAuthStore } from '@/stores/auth-store';
|
|
import { useTenantViewStore } from '@/stores/tenant-view-store';
|
|
import { isGlobalAdminRfc } from '@horux/shared';
|
|
import {
|
|
TrendingUp,
|
|
TrendingDown,
|
|
Wallet,
|
|
Receipt,
|
|
AlertTriangle,
|
|
ShoppingCart,
|
|
CheckSquare,
|
|
FileMinus,
|
|
FilePlus,
|
|
} from 'lucide-react';
|
|
import { cn } from '@horux/shared-ui';
|
|
import { FiscalDisclaimer } from '@/components/fiscal-disclaimer';
|
|
|
|
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 };
|
|
}
|
|
|
|
function shiftDatesOneYear(fechaInicio: string, fechaFin: string, delta: number) {
|
|
const s = new Date(fechaInicio + 'T00:00:00');
|
|
const e = new Date(fechaFin + 'T00:00:00');
|
|
s.setFullYear(s.getFullYear() + delta);
|
|
e.setFullYear(e.getFullYear() + delta);
|
|
// Ajustar último día del mes si cambió
|
|
const lastDay = new Date(e.getFullYear(), e.getMonth() + 1, 0).getDate();
|
|
if (e.getDate() > lastDay) e.setDate(lastDay);
|
|
return {
|
|
fechaInicio: s.toISOString().split('T')[0],
|
|
fechaFin: e.toISOString().split('T')[0],
|
|
};
|
|
}
|
|
|
|
export default function DashboardPage() {
|
|
const router = useRouter();
|
|
const { user } = useAuthStore();
|
|
const { viewingTenantId } = useTenantViewStore();
|
|
// Admin global no opera sobre datos de despacho propios — su home natural
|
|
// es `/clientes`. EXCEPCIÓN: si está impersonando un tenant (vía botón "Ver"
|
|
// en /clientes), sí entra al dashboard para validar lo que ve el cliente.
|
|
const isGlobalAdmin = isGlobalAdminRfc(user?.tenantRfc, user?.role, user?.platformRoles);
|
|
useEffect(() => {
|
|
if (isGlobalAdmin && !viewingTenantId) router.replace('/clientes');
|
|
}, [isGlobalAdmin, viewingTenantId, router]);
|
|
|
|
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 [regimenSeleccionado, setRegimenSeleccionado] = useState<string | null>(null);
|
|
const [conciliacion, setConciliacion] = useState(false);
|
|
|
|
// Periodo anterior (mismo rango, un año atrás)
|
|
const anterior = shiftDatesOneYear(fechaInicio, fechaFin, -1);
|
|
|
|
// Año del inicio para el chart anual
|
|
const añoChart = new Date(fechaInicio + 'T00:00:00').getFullYear();
|
|
const mesResumen = new Date(fechaInicio + 'T00:00:00').getMonth() + 1;
|
|
|
|
const { data: kpis } = useKpis(fechaInicio, fechaFin, conciliacion);
|
|
const { data: kpisAnterior } = useKpis(anterior.fechaInicio, anterior.fechaFin, conciliacion);
|
|
const { data: chartData } = useIngresosEgresos(añoChart, conciliacion);
|
|
const { data: alertas, isLoading: alertasLoading } = useAlertas(5);
|
|
const { data: regimenesPeriodo, isLoading: regimenesLoading } = useRegimenesDelPeriodo(fechaInicio, fechaFin, conciliacion);
|
|
|
|
const handlePeriodChange = (inicio: string, fin: string) => {
|
|
setFechaInicio(inicio);
|
|
setFechaFin(fin);
|
|
};
|
|
|
|
// Filtrar ingresos por régimen seleccionado
|
|
const ingresosDisplay = regimenSeleccionado
|
|
? kpis?.ingresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.ingresos || 0;
|
|
|
|
const ingresosAnterior = regimenSeleccionado
|
|
? kpisAnterior?.ingresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpisAnterior?.ingresos || 0;
|
|
|
|
const ingresosVariacion = ingresosAnterior > 0
|
|
? Math.round(((ingresosDisplay - ingresosAnterior) / ingresosAnterior) * 10000) / 100
|
|
: null;
|
|
|
|
// Filtrar egresos por régimen seleccionado
|
|
const egresosDisplay = regimenSeleccionado
|
|
? kpis?.egresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.egresos || 0;
|
|
|
|
const egresosAnterior = regimenSeleccionado
|
|
? kpisAnterior?.egresosPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpisAnterior?.egresos || 0;
|
|
|
|
const egresosVariacion = egresosAnterior > 0
|
|
? Math.round(((egresosDisplay - egresosAnterior) / egresosAnterior) * 10000) / 100
|
|
: null;
|
|
|
|
// Adquisición de mercancías
|
|
const adquisicionDisplay = regimenSeleccionado
|
|
? kpis?.adquisicionMercanciasPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.adquisicionMercancias || 0;
|
|
|
|
// Filtrar IVA por régimen seleccionado
|
|
const ivaDisplay = regimenSeleccionado
|
|
? kpis?.ivaBalancePorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.ivaBalance || 0;
|
|
|
|
// Notas de crédito
|
|
const ncsEmitidasDisplay = regimenSeleccionado
|
|
? kpis?.ncsEmitidasPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.ncsEmitidas || 0;
|
|
|
|
const ncsRecibidasDisplay = regimenSeleccionado
|
|
? kpis?.ncsRecibidasPorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpis?.ncsRecibidas || 0;
|
|
|
|
const ivaAnterior = regimenSeleccionado
|
|
? kpisAnterior?.ivaBalancePorRegimen?.find(r => r.regimenClave === regimenSeleccionado)?.monto || 0
|
|
: kpisAnterior?.ivaBalance || 0;
|
|
|
|
const ivaVariacion = ivaAnterior !== 0
|
|
? Math.round(((ivaDisplay - ivaAnterior) / Math.abs(ivaAnterior)) * 10000) / 100
|
|
: null;
|
|
|
|
const utilidadDisplay = ingresosDisplay - egresosDisplay;
|
|
const margenDisplay = ingresosDisplay > 0
|
|
? Math.round((utilidadDisplay / ingresosDisplay) * 10000) / 100
|
|
: 0;
|
|
|
|
const formatCurrency = (value: number) =>
|
|
new Intl.NumberFormat('es-MX', {
|
|
style: 'currency',
|
|
currency: 'MXN',
|
|
minimumFractionDigits: 0,
|
|
}).format(value);
|
|
|
|
// Helper para construir URLs de drill-down
|
|
const drillUrl = (titulo: string, filters: Record<string, string>) => {
|
|
const p = new URLSearchParams({ titulo, fechaInicio, fechaFin, status: 'vigente', ...filters });
|
|
// Dashboard no tiene toggles considerarActivos/considerarNCs — siempre
|
|
// pasa los defaults true (omitir = backend usa true). Si en el futuro se
|
|
// agregan toggles aquí, propagarlos como hace /impuestos.
|
|
if (regimenSeleccionado) {
|
|
if (filters.type === 'EMITIDO') p.set('regimenEmisor', regimenSeleccionado);
|
|
else if (filters.type === 'RECIBIDO') p.set('regimenReceptor', regimenSeleccionado);
|
|
// Por bucket — 605 es receptor en bucket=ingresos (nómina recibida).
|
|
else if (filters.bucket === 'ingresos') {
|
|
if (regimenSeleccionado === '605') p.set('regimenReceptor', '605');
|
|
else p.set('regimenEmisor', regimenSeleccionado);
|
|
}
|
|
else if (filters.bucket === 'causado') p.set('regimenEmisor', regimenSeleccionado);
|
|
else if (filters.bucket === 'gastos' || filters.bucket === 'acreditable') p.set('regimenReceptor', regimenSeleccionado);
|
|
}
|
|
return `/drill-down?${p}`;
|
|
};
|
|
|
|
// Año anterior para labels
|
|
const añoAnterior = new Date(anterior.fechaInicio + 'T00:00:00').getFullYear();
|
|
|
|
// Reset régimen si ya no existe en el periodo
|
|
const regimenesDisponibles = regimenesPeriodo || [];
|
|
if (regimenSeleccionado && regimenesDisponibles.length > 0 &&
|
|
!regimenesDisponibles.find(r => r.clave === regimenSeleccionado)) {
|
|
setRegimenSeleccionado(null);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Header title="Dashboard">
|
|
<PeriodSelector
|
|
fechaInicio={fechaInicio}
|
|
fechaFin={fechaFin}
|
|
onChange={handlePeriodChange}
|
|
/>
|
|
</Header>
|
|
<main className="p-6 space-y-6">
|
|
{/* Filtros */}
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<RegimenSelector
|
|
regimenes={regimenesDisponibles}
|
|
selected={regimenSeleccionado}
|
|
onChange={setRegimenSeleccionado}
|
|
isLoading={regimenesLoading}
|
|
/>
|
|
<button
|
|
onClick={() => setConciliacion(!conciliacion)}
|
|
className={cn(
|
|
'flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors',
|
|
conciliacion
|
|
? 'bg-primary/10 text-primary border border-primary/30'
|
|
: 'hover:bg-accent'
|
|
)}
|
|
>
|
|
<CheckSquare className="h-4 w-4" />
|
|
Conciliación
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* KPIs */}
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
<KpiCard
|
|
title={regimenSeleccionado ? `Ingresos del Mes (${regimenSeleccionado})` : 'Ingresos del Mes'}
|
|
value={ingresosDisplay}
|
|
icon={<TrendingUp className="h-4 w-4" />}
|
|
trend={ingresosVariacion !== null ? (ingresosVariacion >= 0 ? 'up' : 'down') : 'neutral'}
|
|
trendValue={
|
|
ingresosVariacion !== null
|
|
? `${ingresosVariacion >= 0 ? '+' : ''}${ingresosVariacion}% vs ${añoAnterior}`
|
|
: 'Sin datos del periodo anterior'
|
|
}
|
|
href={drillUrl('Ingresos del Mes - CFDIs', { bucket: 'ingresos' })}
|
|
/>
|
|
<KpiCard
|
|
title={regimenSeleccionado ? `Gastos del Mes (${regimenSeleccionado})` : 'Gastos del Mes'}
|
|
value={egresosDisplay}
|
|
icon={<TrendingDown className="h-4 w-4" />}
|
|
trend={egresosVariacion !== null ? (egresosVariacion >= 0 ? 'up' : 'down') : 'neutral'}
|
|
trendValue={
|
|
egresosVariacion !== null
|
|
? `${egresosVariacion >= 0 ? '+' : ''}${egresosVariacion}% vs ${añoAnterior}`
|
|
: 'Sin datos del periodo anterior'
|
|
}
|
|
href={drillUrl('Gastos del Mes - CFDIs', { bucket: 'gastos' })}
|
|
/>
|
|
<KpiCard
|
|
title="Utilidad"
|
|
value={utilidadDisplay}
|
|
icon={<Wallet className="h-4 w-4" />}
|
|
trend={utilidadDisplay > 0 ? 'up' : 'down'}
|
|
trendValue={`${margenDisplay}% margen`}
|
|
/>
|
|
<KpiCard
|
|
title={regimenSeleccionado ? `Balance IVA (${regimenSeleccionado})` : 'Balance IVA'}
|
|
value={ivaDisplay}
|
|
icon={<Receipt className="h-4 w-4" />}
|
|
trend={ivaDisplay > 0 ? 'up' : ivaDisplay < 0 ? 'down' : 'neutral'}
|
|
trendValue={ivaDisplay > 0 ? 'Por pagar' : ivaDisplay < 0 ? 'A favor' : 'Neutro'}
|
|
subtitle={
|
|
ivaVariacion !== null
|
|
? `${ivaVariacion >= 0 ? '+' : ''}${ivaVariacion}% vs ${añoAnterior}`
|
|
: undefined
|
|
}
|
|
href={drillUrl('Balance IVA - CFDIs', {})}
|
|
/>
|
|
<KpiCard
|
|
title={regimenSeleccionado ? `NCs Emitidas (${regimenSeleccionado})` : 'NCs Emitidas'}
|
|
value={ncsEmitidasDisplay}
|
|
icon={<FileMinus className="h-4 w-4" />}
|
|
trend="neutral"
|
|
trendValue="Notas de crédito emitidas"
|
|
/>
|
|
<KpiCard
|
|
title={regimenSeleccionado ? `NCs Recibidas (${regimenSeleccionado})` : 'NCs Recibidas'}
|
|
value={ncsRecibidasDisplay}
|
|
icon={<FilePlus className="h-4 w-4" />}
|
|
trend="neutral"
|
|
trendValue="Notas de crédito recibidas"
|
|
/>
|
|
</div>
|
|
|
|
{/* Desglose por régimen */}
|
|
{!regimenSeleccionado && kpis && (
|
|
(kpis.ingresosPorRegimen.length > 1 || kpis.egresosPorRegimen.length > 1 || kpis.ivaBalancePorRegimen.length > 1 || kpis.ncsEmitidasPorRegimen.length > 1 || kpis.ncsRecibidasPorRegimen.length > 1) && (
|
|
<div className="grid gap-4 md:grid-cols-2 3xl:grid-cols-3">
|
|
{kpis.ingresosPorRegimen.length > 1 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base font-medium">Ingresos por Regimen</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
{kpis.ingresosPorRegimen.map((r) => (
|
|
<div key={r.regimenClave} className="flex items-center justify-between py-2 border-b last:border-0">
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-xs font-mono font-bold bg-muted px-2 py-1 rounded">{r.regimenClave}</span>
|
|
<span className="text-sm">{r.regimenDescripcion}</span>
|
|
</div>
|
|
<span className="text-sm font-semibold">{formatCurrency(r.monto)}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
{kpis.egresosPorRegimen.length > 1 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base font-medium">Gastos por Regimen</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
{kpis.egresosPorRegimen.map((r) => (
|
|
<div key={r.regimenClave} className="flex items-center justify-between py-2 border-b last:border-0">
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-xs font-mono font-bold bg-muted px-2 py-1 rounded">{r.regimenClave}</span>
|
|
<span className="text-sm">{r.regimenDescripcion}</span>
|
|
</div>
|
|
<span className="text-sm font-semibold">{formatCurrency(r.monto)}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
{kpis.ivaBalancePorRegimen.length > 1 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base font-medium">Balance IVA por Regimen</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
{kpis.ivaBalancePorRegimen.map((r) => (
|
|
<div key={r.regimenClave} className="flex items-center justify-between py-2 border-b last:border-0">
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-xs font-mono font-bold bg-muted px-2 py-1 rounded">{r.regimenClave}</span>
|
|
<span className="text-sm">{r.regimenDescripcion}</span>
|
|
</div>
|
|
<span className={`text-sm font-semibold ${r.monto > 0 ? 'text-destructive' : 'text-success'}`}>
|
|
{formatCurrency(r.monto)}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
{kpis.ncsEmitidasPorRegimen.length > 1 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base font-medium">NCs Emitidas por Regimen</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
{kpis.ncsEmitidasPorRegimen.map((r) => (
|
|
<div key={r.regimenClave} className="flex items-center justify-between py-2 border-b last:border-0">
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-xs font-mono font-bold bg-muted px-2 py-1 rounded">{r.regimenClave}</span>
|
|
<span className="text-sm">{r.regimenDescripcion}</span>
|
|
</div>
|
|
<span className="text-sm font-semibold">{formatCurrency(r.monto)}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
{kpis.ncsRecibidasPorRegimen.length > 1 && (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base font-medium">NCs Recibidas por Regimen</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<div className="space-y-2">
|
|
{kpis.ncsRecibidasPorRegimen.map((r) => (
|
|
<div key={r.regimenClave} className="flex items-center justify-between py-2 border-b last:border-0">
|
|
<div className="flex items-center gap-3">
|
|
<span className="text-xs font-mono font-bold bg-muted px-2 py-1 rounded">{r.regimenClave}</span>
|
|
<span className="text-sm">{r.regimenDescripcion}</span>
|
|
</div>
|
|
<span className="text-sm font-semibold">{formatCurrency(r.monto)}</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
</div>
|
|
))}
|
|
|
|
{/* Charts and Alerts */}
|
|
<div className="grid gap-6 lg:grid-cols-3">
|
|
<div className="lg:col-span-2">
|
|
<BarChart
|
|
title="Ingresos vs Egresos"
|
|
data={chartData || []}
|
|
/>
|
|
</div>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2 text-base font-medium">
|
|
<AlertTriangle className="h-4 w-4" />
|
|
Alertas
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
{alertasLoading ? (
|
|
<p className="text-sm text-muted-foreground">Cargando...</p>
|
|
) : alertas?.length === 0 ? (
|
|
<p className="text-sm text-muted-foreground">No hay alertas pendientes</p>
|
|
) : (
|
|
alertas?.map((alerta) => (
|
|
<div
|
|
key={alerta.id}
|
|
className={`p-3 rounded-lg border ${
|
|
alerta.prioridad === 'alta'
|
|
? 'border-destructive/50 bg-destructive/10'
|
|
: 'border-border bg-muted/50'
|
|
}`}
|
|
>
|
|
<p className="text-sm font-medium">{alerta.titulo}</p>
|
|
<p className="text-xs text-muted-foreground mt-1">
|
|
{alerta.mensaje}
|
|
</p>
|
|
</div>
|
|
))
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Resumen Fiscal */}
|
|
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-5">
|
|
<Card>
|
|
<CardContent className="p-4">
|
|
<p className="text-sm text-muted-foreground">CFDIs Emitidos</p>
|
|
<p className="text-2xl font-bold">{
|
|
regimenSeleccionado
|
|
? kpis?.cfdisEmitidosPorRegimen?.find(r => r.regimen === regimenSeleccionado)?.total || 0
|
|
: kpis?.cfdisEmitidos || 0
|
|
}</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardContent className="p-4">
|
|
<p className="text-sm text-muted-foreground">CFDIs Recibidos</p>
|
|
<p className="text-2xl font-bold">{
|
|
regimenSeleccionado
|
|
? kpis?.cfdisRecibidosPorRegimen?.find(r => r.regimen === regimenSeleccionado)?.total || 0
|
|
: kpis?.cfdisRecibidos || 0
|
|
}</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardContent className="p-4">
|
|
<div className="flex items-center gap-2">
|
|
<ShoppingCart className="h-4 w-4 text-muted-foreground" />
|
|
<p className="text-sm text-muted-foreground">Adquisición de Mercancías</p>
|
|
</div>
|
|
<p className="text-2xl font-bold">{formatCurrency(adquisicionDisplay)}</p>
|
|
<p className="text-xs text-muted-foreground mt-1">Uso CFDI G01</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardContent className="p-4">
|
|
<p className="text-sm text-muted-foreground">IVA a Favor ({añoChart})</p>
|
|
<p className="text-2xl font-bold text-success">
|
|
{formatCurrency(kpis?.ivaAFavorAcumulado || 0)}
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardContent className="p-4">
|
|
<p className="text-sm text-muted-foreground">IVA a Favor Historico</p>
|
|
<p className="text-2xl font-bold text-success">
|
|
{formatCurrency(kpis?.ivaAFavorHistorico || 0)}
|
|
</p>
|
|
<p className="text-xs text-muted-foreground mt-1">{añoChart - 5} — {añoChart}</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
<FiscalDisclaimer />
|
|
</main>
|
|
</>
|
|
);
|
|
}
|