feat: bulk XML upload, period selector, and session persistence

- Add bulk XML CFDI upload support (up to 300MB)
- Add period selector component for month/year navigation
- Fix session persistence on page refresh (Zustand hydration)
- Fix income/expense classification based on tenant RFC
- Fix IVA calculation from XML (correct Impuestos element)
- Add error handling to reportes page
- Support multiple CORS origins
- Update reportes service with proper Decimal/BigInt handling
- Add RFC to tenant view store for proper CFDI classification
- Update README with changelog and new features

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Consultoria AS
2026-01-22 06:51:53 +00:00
parent 0c10c887d2
commit c3ce7199af
37 changed files with 1680 additions and 216 deletions

View File

@@ -5,20 +5,20 @@ import { Header } from '@/components/layouts/header';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { KpiCard } from '@/components/charts/kpi-card';
import { PeriodSelector } from '@/components/period-selector';
import { useIvaMensual, useResumenIva, useResumenIsr } from '@/lib/hooks/use-impuestos';
import { Calculator, TrendingUp, TrendingDown, Receipt } from 'lucide-react';
const meses = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
export default function ImpuestosPage() {
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1;
const [año] = useState(currentYear);
const [año, setAño] = useState(new Date().getFullYear());
const [mes, setMes] = useState(new Date().getMonth() + 1);
const [activeTab, setActiveTab] = useState<'iva' | 'isr'>('iva');
const { data: ivaMensual, isLoading: ivaLoading } = useIvaMensual(año);
const { data: resumenIva } = useResumenIva(año, currentMonth);
const { data: resumenIsr } = useResumenIsr(año, currentMonth);
const { data: resumenIva } = useResumenIva(año, mes);
const { data: resumenIsr } = useResumenIsr(año, mes);
const formatCurrency = (value: number) =>
new Intl.NumberFormat('es-MX', {
@@ -29,7 +29,14 @@ export default function ImpuestosPage() {
return (
<>
<Header title="Control de Impuestos" />
<Header title="Control de Impuestos">
<PeriodSelector
año={año}
mes={mes}
onAñoChange={setAño}
onMesChange={setMes}
/>
</Header>
<main className="p-6 space-y-6">
{/* Tabs */}
<div className="flex gap-2">