'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; noIdentificacion?: 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) => { const d = new Date(dateString); d.setHours(d.getHours() - 1); return d.toLocaleDateString('es-MX', { day: '2-digit', month: 'long', year: 'numeric', }); }; const formatDateTime = (dateString: string) => { const d = new Date(dateString); d.setHours(d.getHours() - 1); return d.toLocaleString('es-MX', { day: '2-digit', month: 'short', year: 'numeric', hour: '2-digit', minute: '2-digit', }); }; const typeLabels: Record = { EMITIDO: 'Emitido', RECIBIDO: 'Recibido', }; const tipoCompLabels: Record = { I: 'Ingreso', E: 'Egreso', T: 'Traslado', P: 'Pago', N: '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 regimenFiscalLabels: Record = { '601': 'General de Ley Personas Morales', '603': 'Personas Morales con Fines no Lucrativos', '605': 'Sueldos y Salarios e Ingresos Asimilados a Salarios', '606': 'Arrendamiento', '608': 'Demás ingresos', '609': 'Consolidación', '610': 'Residentes en el Extranjero sin Establecimiento Permanente en México', '611': 'Ingresos por Dividendos (socios y accionistas)', '612': 'Personas Físicas con Actividades Empresariales y Profesionales', '614': 'Ingresos por intereses', '615': 'Régimen de los ingresos por obtención de premios', '616': 'Sin obligaciones fiscales', '620': 'Sociedades Cooperativas de Producción que optan por diferir sus ingresos', '621': 'Incorporación Fiscal', '622': 'Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras', '623': 'Opcional para Grupos de Sociedades', '624': 'Coordinados', '625': 'Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas', '626': 'Régimen Simplificado de Confianza', }; const tipoRelacionLabels: Record = { '01': 'Nota de crédito', '02': 'Nota de débito', '03': 'Devolución de mercancía', '04': 'Sustitución de CFDI previo', '05': 'Traslados de mercancias facturados previamente', '06': 'Factura generada por traslados previos', '07': 'CFDI por aplicación de anticipo', }; 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.status === 'Vigente' || cfdi.status === '1' ? 'VIGENTE' : 'CANCELADO'} {typeLabels[cfdi.type] || cfdi.type} {cfdi.tipoComprobante ? `(${tipoCompLabels[cfdi.tipoComprobante] || cfdi.tipoComprobante})` : ''}
{cfdi.serie && {cfdi.serie}-} {cfdi.folio || 'S/N'}

{cfdi.tipoComprobante === 'P' && cfdi.fechaPagoP ? `Pago: ${formatDate(cfdi.fechaPagoP)}` : formatDate(cfdi.fechaEmision)}

{/* Receptor */}

Receptor

{cfdi.nombreReceptor}

RFC: {cfdi.rfcReceptor} {cfdi.codigoPostalReceptor && ( C.P.: {cfdi.codigoPostalReceptor} )} {cfdi.regimenFiscalReceptor && ( Régimen: {cfdi.regimenFiscalReceptor} {regimenFiscalLabels[cfdi.regimenFiscalReceptor] ? ` — ${regimenFiscalLabels[cfdi.regimenFiscalReceptor]}` : ''} )}
{cfdi.usoCfdi && (

Uso CFDI

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

)}
{/* CFDIs Relacionados (no-P) */} {(cfdi.cfdiTipoRelacion || cfdi.cfdisRelacionados) && cfdi.tipoComprobante !== 'P' && (

CFDI Relacionado

{cfdi.cfdiTipoRelacion && (

Tipo de relación:{' '} {cfdi.cfdiTipoRelacion} — {tipoRelacionLabels[cfdi.cfdiTipoRelacion] || 'Desconocido'}

)} {cfdi.cfdisRelacionados && (
UUIDs relacionados:
{cfdi.cfdisRelacionados.split('|').map((uuid) => uuid.trim()).filter(Boolean).map((uuid, idx) => ( {uuid} ))}
)}
)} {/* Complemento de Pago (solo tipo P) */} {cfdi.tipoComprobante === 'P' && (

Complemento de Pago

{cfdi.montoPago > 0 && (
Monto pagado {formatCurrency(cfdi.montoPago)}
)} {cfdi.fechaPagoP && (
Fecha de pago {formatDate(cfdi.fechaPagoP)}
)} {cfdi.numParcialidad && (
Parcialidad {cfdi.numParcialidad}
)} {cfdi.uuidRelacionado && (
UUID relacionado (factura pagada):
{cfdi.uuidRelacionado.split('|').map((uuid) => uuid.trim()).filter(Boolean).map((uuid, idx) => ( {uuid} ))}
)} {cfdi.saldoInsoluto && (
Saldo insoluto {cfdi.saldoInsoluto}
)} {/* Impuestos del pago */} {(cfdi.isrRetencionPago > 0 || cfdi.ivaTrasladoPago > 0 || cfdi.ivaRetencionPago > 0 || cfdi.iepsTrasladoPago > 0 || cfdi.iepsRetencionPago > 0) && (

Impuestos del pago

{cfdi.isrRetencionPago > 0 && (
ISR Ret.-{formatCurrency(cfdi.isrRetencionPago)}
)} {cfdi.ivaTrasladoPago > 0 && (
IVA Tras.{formatCurrency(cfdi.ivaTrasladoPago)}
)} {cfdi.ivaRetencionPago > 0 && (
IVA Ret.-{formatCurrency(cfdi.ivaRetencionPago)}
)} {cfdi.iepsTrasladoPago > 0 && (
IEPS Tras.{formatCurrency(cfdi.iepsTrasladoPago)}
)} {cfdi.iepsRetencionPago > 0 && (
IEPS Ret.-{formatCurrency(cfdi.iepsRetencionPago)}
)}
)}
)} {/* 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 — ocultar para tipo P (concepto dummy) */} {conceptos && conceptos.length > 0 && cfdi.tipoComprobante !== 'P' && (

Conceptos

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

{concepto.descripcion}

{concepto.claveProdServ && (

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

)}
{concepto.noIdentificacion || } {concepto.cantidad} {formatCurrency(concepto.valorUnitario)} {formatCurrency(concepto.importe)}
)} {/* Totales — ocultar bloque tradicional para tipo P */} {cfdi.tipoComprobante !== 'P' && (
Subtotal {formatCurrency(cfdi.subtotal)}
{cfdi.descuento > 0 && (
Descuento -{formatCurrency(cfdi.descuento)}
)} {cfdi.ivaTraslado > 0 && (
IVA (16%) {formatCurrency(cfdi.ivaTraslado)}
)} {cfdi.ivaRetencion > 0 && (
IVA Retenido -{formatCurrency(cfdi.ivaRetencion)}
)} {cfdi.isrRetencion > 0 && (
ISR Retenido -{formatCurrency(cfdi.isrRetencion)}
)}
TOTAL {formatCurrency(cfdi.total)}
)} {/* Timbre Fiscal Digital */}
{/* QR Placeholder */}
QR
{/* Info del Timbre */}

Timbre Fiscal Digital

UUID: {cfdi.uuid}
{cfdi.fechaCertSat && (<> Fecha Certificación SAT: {formatDateTime(cfdi.fechaCertSat)} )}
{/* Leyenda */}

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

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