Design for PDF-like invoice visualization with: - Modal viewer with invoice preview - PDF download via html2pdf.js - XML download from stored data Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5.8 KiB
5.8 KiB
Diseño: Visor de CFDI
Fecha: 2026-02-17 Estado: Aprobado
Resumen
Agregar funcionalidad para visualizar facturas CFDI en formato PDF-like, recreando la representación visual desde el XML almacenado. Incluye descarga de PDF y XML.
Decisiones de Diseño
- Tipo de vista: PDF-like (representación visual similar a factura impresa)
- Acceso: Botón "Ver" (icono ojo) en cada fila de la tabla
- Acciones: Descargar PDF, Descargar XML
- Enfoque técnico: Componente React + html2pdf.js para generación de PDF en cliente
Arquitectura de Componentes
CfdiPage (existente)
├── Tabla de CFDIs
│ └── Botón "Ver" (Eye icon) → abre modal
│
└── CfdiViewerModal (NUEVO)
├── Header: Título + Botones (PDF, XML, Cerrar)
└── CfdiInvoice (NUEVO)
├── Encabezado (Emisor + Receptor)
├── Datos del comprobante
├── Tabla de conceptos (parseados del XML)
├── Totales e impuestos
└── Timbre fiscal (UUID, fechas)
Componentes Nuevos
| Componente | Ubicación | Responsabilidad |
|---|---|---|
CfdiViewerModal |
components/cfdi/cfdi-viewer-modal.tsx |
Modal con visor y botones de acción |
CfdiInvoice |
components/cfdi/cfdi-invoice.tsx |
Renderiza la factura estilo PDF |
Diseño Visual
┌──────────────────────────────────────────────────────────────┐
│ ┌─────────────────┐ FACTURA │
│ │ [LOGO] │ Serie: A Folio: 001 │
│ │ placeholder │ Fecha: 15/Ene/2025 │
│ └─────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ EMISOR │ RECEPTOR │
│ Empresa Emisora SA de CV │ Cliente SA de CV │
│ RFC: XAXX010101000 │ RFC: XAXX010101001 │
│ │ Uso CFDI: G03 │
├──────────────────────────────────────────────────────────────┤
│ DATOS DEL COMPROBANTE │
│ Tipo: Ingreso Método: PUE Forma: 03 - Transferencia │
│ Moneda: MXN Tipo Cambio: 1.00 │
├──────────────────────────────────────────────────────────────┤
│ CONCEPTOS │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Descripción │ Cant │ P. Unit │ Importe │ │
│ ├──────────────────────────────────────────────────────┤ │
│ │ Servicio consultoría │ 1 │ 10,000 │ 10,000.00 │ │
│ └──────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Subtotal: $10,000.00 │
│ IVA 16%: $1,600.00 │
│ TOTAL: $11,600.00 │
├──────────────────────────────────────────────────────────────┤
│ TIMBRE FISCAL DIGITAL │
│ UUID: 12345678-1234-1234-1234-123456789012 │
│ Fecha Timbrado: 2025-01-15T12:30:45 │
└──────────────────────────────────────────────────────────────┘
Flujo de Datos
- Usuario hace clic en "Ver" (Eye icon)
- Se abre CfdiViewerModal con el CFDI seleccionado
- Si existe xmlOriginal:
- Parsear XML para extraer conceptos
- Mostrar factura completa
- Si no existe XML:
- Mostrar factura con datos de BD (sin conceptos)
- Acciones disponibles:
- Descargar PDF (html2pdf genera PDF)
- Descargar XML (si existe)
Cambios en Backend
Nuevo Endpoint
GET /api/cfdi/:id/xml
Retorna el XML original del CFDI.
Modificar Endpoint Existente
GET /api/cfdi/:id
Agregar campo xmlOriginal a la respuesta.
Dependencias
{
"html2pdf.js": "^0.10.1"
}
Archivos a Crear/Modificar
Nuevos
apps/web/components/cfdi/cfdi-viewer-modal.tsxapps/web/components/cfdi/cfdi-invoice.tsxapps/api/src/controllers/cfdi.controller.ts(nuevo método getXml)
Modificar
apps/web/app/(dashboard)/cfdi/page.tsx(agregar botón Ver y modal)apps/api/src/routes/cfdi.routes.ts(agregar ruta /xml)apps/api/src/services/cfdi.service.ts(agregar método getXmlById)packages/shared/src/types/cfdi.ts(agregar xmlOriginal a Cfdi)