'use client'; import { forwardRef } from 'react'; import type { Cfdi } from '@horux/shared'; interface CfdiConcepto { descripcion: string; cantidad: number; valorUnitario: number; importe: number; claveUnidad?: string; claveProdServ?: string; } interface CfdiInvoiceProps { cfdi: Cfdi; conceptos?: CfdiConcepto[]; } const formatCurrency = (value: number) => new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN', }).format(value); const formatDate = (dateString: string) => new Date(dateString).toLocaleDateString('es-MX', { day: '2-digit', month: 'long', year: 'numeric', }); const formatDateTime = (dateString: string) => new Date(dateString).toLocaleString('es-MX', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', }); const tipoLabels: Record = { ingreso: 'Ingreso', egreso: 'Egreso', traslado: 'Traslado', pago: 'Pago', nomina: 'Nómina', }; const formaPagoLabels: Record = { '01': 'Efectivo', '02': 'Cheque nominativo', '03': 'Transferencia electrónica', '04': 'Tarjeta de crédito', '28': 'Tarjeta de débito', '99': 'Por definir', }; const metodoPagoLabels: Record = { PUE: 'Pago en una sola exhibición', PPD: 'Pago en parcialidades o diferido', }; const usoCfdiLabels: Record = { G01: 'Adquisición de mercancías', G02: 'Devoluciones, descuentos o bonificaciones', G03: 'Gastos en general', I01: 'Construcciones', I02: 'Mobilario y equipo de oficina', I03: 'Equipo de transporte', I04: 'Equipo de cómputo', I05: 'Dados, troqueles, moldes', I06: 'Comunicaciones telefónicas', I07: 'Comunicaciones satelitales', I08: 'Otra maquinaria y equipo', D01: 'Honorarios médicos', D02: 'Gastos médicos por incapacidad', D03: 'Gastos funerales', D04: 'Donativos', D05: 'Intereses por créditos hipotecarios', D06: 'Aportaciones voluntarias SAR', D07: 'Primas por seguros de gastos médicos', D08: 'Gastos de transportación escolar', D09: 'Depósitos en cuentas para el ahorro', D10: 'Pagos por servicios educativos', P01: 'Por definir', S01: 'Sin efectos fiscales', CP01: 'Pagos', CN01: 'Nómina', }; export const CfdiInvoice = forwardRef( ({ cfdi, conceptos }, ref) => { return (
{/* Header con gradiente */}

Emisor

{cfdi.nombreEmisor}

RFC: {cfdi.rfcEmisor}

{cfdi.estado === 'vigente' ? 'VIGENTE' : 'CANCELADO'} {tipoLabels[cfdi.tipo] || cfdi.tipo}
{cfdi.serie && {cfdi.serie}-} {cfdi.folio || 'S/N'}

{formatDate(cfdi.fechaEmision)}

{/* Receptor */}

Receptor

{cfdi.nombreReceptor}

RFC: {cfdi.rfcReceptor}

{cfdi.usoCfdi && (

Uso CFDI

{cfdi.usoCfdi} - {usoCfdiLabels[cfdi.usoCfdi] || ''}

)}
{/* Datos del Comprobante */}

Método Pago

{cfdi.metodoPago || '-'}

{cfdi.metodoPago ? metodoPagoLabels[cfdi.metodoPago] || '' : ''}

Forma Pago

{cfdi.formaPago || '-'}

{cfdi.formaPago ? formaPagoLabels[cfdi.formaPago] || '' : ''}

Moneda

{cfdi.moneda || 'MXN'}

{cfdi.tipoCambio && cfdi.tipoCambio !== 1 && (

TC: {cfdi.tipoCambio}

)}

Versión

CFDI 4.0

{/* Conceptos */} {conceptos && conceptos.length > 0 && (

Conceptos

{conceptos.map((concepto, idx) => ( ))}
Descripción Cant. P. Unitario Importe

{concepto.descripcion}

{concepto.claveProdServ && (

Clave: {concepto.claveProdServ} {concepto.claveUnidad && ` | Unidad: ${concepto.claveUnidad}`}

)}
{concepto.cantidad} {formatCurrency(concepto.valorUnitario)} {formatCurrency(concepto.importe)}
)} {/* Totales */}
Subtotal {formatCurrency(cfdi.subtotal)}
{cfdi.descuento > 0 && (
Descuento -{formatCurrency(cfdi.descuento)}
)} {cfdi.iva > 0 && (
IVA (16%) {formatCurrency(cfdi.iva)}
)} {cfdi.ivaRetenido > 0 && (
IVA Retenido -{formatCurrency(cfdi.ivaRetenido)}
)} {cfdi.isrRetenido > 0 && (
ISR Retenido -{formatCurrency(cfdi.isrRetenido)}
)}
TOTAL {formatCurrency(cfdi.total)}
{/* Timbre Fiscal Digital */}
{/* QR Placeholder */}
QR
{/* Info del Timbre */}

Timbre Fiscal Digital

UUID: {cfdi.uuidFiscal}
Fecha de Timbrado: {formatDateTime(cfdi.fechaTimbrado)}
{/* Leyenda */}

Este documento es una representación impresa de un CFDI • Verificable en: https://verificacfdi.facturaelectronica.sat.gob.mx

); } ); CfdiInvoice.displayName = 'CfdiInvoice';