feat(cfdi): agrega C.P. receptor, regimen receptor, no_identificacion, tipo_relacion y CFDIs relacionados al visualizador
Backend: - Migracion 044: codigo_postal_receptor VARCHAR(5) + indice - sat-parser: extrae DomicilioFiscalReceptor - sat.service: persiste codigo_postal_receptor en INSERT/UPDATE - cfdi.service: incluye codigo_postal_receptor en CFDI_SELECT - shared/types: codigoPostalReceptor en interfaz Cfdi Frontend: - cfdi-invoice: tarjeta receptor con C.P. y regimen (con descripciones) - cfdi-invoice: seccion CFDI Relacionado (tipo + UUIDs) - cfdi-invoice: columna No. Identificacion en tabla de conceptos - cfdi-viewer-modal: mapea noIdentificacion desde DB y XML
This commit is contained in:
2
apps/api/src/migrations/tenant/044_cfdi_cp_receptor.sql
Normal file
2
apps/api/src/migrations/tenant/044_cfdi_cp_receptor.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
-- Agregar código postal del receptor al CFDI (extraído del XML durante sync SAT)
|
||||||
|
ALTER TABLE cfdis ADD COLUMN IF NOT EXISTS codigo_postal_receptor VARCHAR(5);
|
||||||
@@ -60,6 +60,7 @@ const CFDI_SELECT = `
|
|||||||
conciliado,
|
conciliado,
|
||||||
regimen_fiscal_emisor as "regimenFiscalEmisor",
|
regimen_fiscal_emisor as "regimenFiscalEmisor",
|
||||||
regimen_fiscal_receptor as "regimenFiscalReceptor",
|
regimen_fiscal_receptor as "regimenFiscalReceptor",
|
||||||
|
codigo_postal_receptor as "codigoPostalReceptor",
|
||||||
xml_url as "xmlUrl", pdf_url as "pdfUrl",
|
xml_url as "xmlUrl", pdf_url as "pdfUrl",
|
||||||
xml_original as "xmlOriginal",
|
xml_original as "xmlOriginal",
|
||||||
cfdi_tipo_relacion as "cfdiTipoRelacion",
|
cfdi_tipo_relacion as "cfdiTipoRelacion",
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ interface CfdiParsed {
|
|||||||
|
|
||||||
regimenFiscalEmisor: string | null;
|
regimenFiscalEmisor: string | null;
|
||||||
regimenFiscalReceptor: string | null;
|
regimenFiscalReceptor: string | null;
|
||||||
|
codigoPostalReceptor: string | null;
|
||||||
// CfdiRelacionados a nivel raíz del comprobante (CFDI 4.0).
|
// CfdiRelacionados a nivel raíz del comprobante (CFDI 4.0).
|
||||||
// `cfdiTipoRelacion` — clave SAT (01..07). NULL si no hay relación.
|
// `cfdiTipoRelacion` — clave SAT (01..07). NULL si no hay relación.
|
||||||
// `cfdisRelacionados` — UUIDs pipe-separated.
|
// `cfdisRelacionados` — UUIDs pipe-separated.
|
||||||
@@ -541,6 +542,7 @@ export function parseXml(xmlContent: string, downloadType: 'emitidos' | 'recibid
|
|||||||
pac: timbreData.pac,
|
pac: timbreData.pac,
|
||||||
regimenFiscalEmisor: emisor['@_RegimenFiscal'] || null,
|
regimenFiscalEmisor: emisor['@_RegimenFiscal'] || null,
|
||||||
regimenFiscalReceptor: receptor['@_RegimenFiscalReceptor'] || receptor['@_RegimenFiscal'] || null,
|
regimenFiscalReceptor: receptor['@_RegimenFiscalReceptor'] || receptor['@_RegimenFiscal'] || null,
|
||||||
|
codigoPostalReceptor: receptor['@_DomicilioFiscalReceptor'] || null,
|
||||||
cfdiTipoRelacion: relacionesData.tipoRelacion,
|
cfdiTipoRelacion: relacionesData.tipoRelacion,
|
||||||
cfdisRelacionados: relacionesData.uuids,
|
cfdisRelacionados: relacionesData.uuids,
|
||||||
// Impuestos comprobante
|
// Impuestos comprobante
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ async function saveCfdis(
|
|||||||
cfdi.otrasDeduccionesNomina, m(cfdi.otrasDeduccionesNomina),
|
cfdi.otrasDeduccionesNomina, m(cfdi.otrasDeduccionesNomina),
|
||||||
cfdi.subsidioCausado, m(cfdi.subsidioCausado),
|
cfdi.subsidioCausado, m(cfdi.subsidioCausado),
|
||||||
cfdi.regimenFiscalEmisor, cfdi.regimenFiscalReceptor,
|
cfdi.regimenFiscalEmisor, cfdi.regimenFiscalReceptor,
|
||||||
|
cfdi.codigoPostalReceptor,
|
||||||
cfdi.xmlOriginal,
|
cfdi.xmlOriginal,
|
||||||
cfdi.cfdiTipoRelacion, cfdi.cfdisRelacionados,
|
cfdi.cfdiTipoRelacion, cfdi.cfdisRelacionados,
|
||||||
jobId,
|
jobId,
|
||||||
@@ -259,9 +260,10 @@ async function saveCfdis(
|
|||||||
otras_deducciones_nomina=$76, otras_deducciones_nomina_mxn=$77,
|
otras_deducciones_nomina=$76, otras_deducciones_nomina_mxn=$77,
|
||||||
subsidio_causado=$78, subsidio_causado_mxn=$79,
|
subsidio_causado=$78, subsidio_causado_mxn=$79,
|
||||||
regimen_fiscal_emisor=$80, regimen_fiscal_receptor=$81,
|
regimen_fiscal_emisor=$80, regimen_fiscal_receptor=$81,
|
||||||
xml_original=$82,
|
codigo_postal_receptor=$82,
|
||||||
cfdi_tipo_relacion=$83, cfdis_relacionados=$84,
|
xml_original=$83,
|
||||||
last_sat_sync=NOW(), sat_sync_job_id=$85::uuid,
|
cfdi_tipo_relacion=$84, cfdis_relacionados=$85,
|
||||||
|
last_sat_sync=NOW(), sat_sync_job_id=$86::uuid,
|
||||||
actualizado_en=NOW()
|
actualizado_en=NOW()
|
||||||
WHERE uuid = $1`,
|
WHERE uuid = $1`,
|
||||||
[cfdi.uuid, ...vals]
|
[cfdi.uuid, ...vals]
|
||||||
@@ -307,6 +309,7 @@ async function saveCfdis(
|
|||||||
otras_deducciones_nomina, otras_deducciones_nomina_mxn,
|
otras_deducciones_nomina, otras_deducciones_nomina_mxn,
|
||||||
subsidio_causado, subsidio_causado_mxn,
|
subsidio_causado, subsidio_causado_mxn,
|
||||||
regimen_fiscal_emisor, regimen_fiscal_receptor,
|
regimen_fiscal_emisor, regimen_fiscal_receptor,
|
||||||
|
codigo_postal_receptor,
|
||||||
xml_original,
|
xml_original,
|
||||||
cfdi_tipo_relacion, cfdis_relacionados,
|
cfdi_tipo_relacion, cfdis_relacionados,
|
||||||
source, sat_sync_job_id, last_sat_sync, contribuyente_id
|
source, sat_sync_job_id, last_sat_sync, contribuyente_id
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ interface CfdiConcepto {
|
|||||||
importe: number;
|
importe: number;
|
||||||
claveUnidad?: string;
|
claveUnidad?: string;
|
||||||
claveProdServ?: string;
|
claveProdServ?: string;
|
||||||
|
noIdentificacion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CfdiInvoiceProps {
|
interface CfdiInvoiceProps {
|
||||||
@@ -66,6 +67,38 @@ const metodoPagoLabels: Record<string, string> = {
|
|||||||
PPD: 'Pago en parcialidades o diferido',
|
PPD: 'Pago en parcialidades o diferido',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const regimenFiscalLabels: Record<string, string> = {
|
||||||
|
'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<string, string> = {
|
||||||
|
'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<string, string> = {
|
const usoCfdiLabels: Record<string, string> = {
|
||||||
G01: 'Adquisición de mercancías',
|
G01: 'Adquisición de mercancías',
|
||||||
G02: 'Devoluciones, descuentos o bonificaciones',
|
G02: 'Devoluciones, descuentos o bonificaciones',
|
||||||
@@ -142,13 +175,26 @@ export const CfdiInvoice = forwardRef<HTMLDivElement, CfdiInvoiceProps>(
|
|||||||
{/* Receptor */}
|
{/* Receptor */}
|
||||||
<div className="bg-gray-50 rounded-lg p-4 mb-5 border-l-4 border-blue-600">
|
<div className="bg-gray-50 rounded-lg p-4 mb-5 border-l-4 border-blue-600">
|
||||||
<div className="flex items-start justify-between">
|
<div className="flex items-start justify-between">
|
||||||
<div>
|
<div className="flex-1 min-w-0">
|
||||||
<p className="text-xs text-gray-500 uppercase tracking-wide font-medium">Receptor</p>
|
<p className="text-xs text-gray-500 uppercase tracking-wide font-medium">Receptor</p>
|
||||||
<p className="text-lg font-semibold text-gray-800 mt-1">{cfdi.nombreReceptor}</p>
|
<p className="text-lg font-semibold text-gray-800 mt-1">{cfdi.nombreReceptor}</p>
|
||||||
<p className="text-gray-600 text-sm">RFC: {cfdi.rfcReceptor}</p>
|
<div className="flex flex-wrap items-center gap-x-4 gap-y-1 mt-1 text-sm text-gray-600">
|
||||||
|
<span>RFC: {cfdi.rfcReceptor}</span>
|
||||||
|
{cfdi.codigoPostalReceptor && (
|
||||||
|
<span>C.P.: {cfdi.codigoPostalReceptor}</span>
|
||||||
|
)}
|
||||||
|
{cfdi.regimenFiscalReceptor && (
|
||||||
|
<span>
|
||||||
|
Régimen: {cfdi.regimenFiscalReceptor}
|
||||||
|
{regimenFiscalLabels[cfdi.regimenFiscalReceptor]
|
||||||
|
? ` — ${regimenFiscalLabels[cfdi.regimenFiscalReceptor]}`
|
||||||
|
: ''}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{cfdi.usoCfdi && (
|
{cfdi.usoCfdi && (
|
||||||
<div className="text-right">
|
<div className="text-right ml-4 flex-shrink-0">
|
||||||
<p className="text-xs text-gray-500 uppercase tracking-wide font-medium">Uso CFDI</p>
|
<p className="text-xs text-gray-500 uppercase tracking-wide font-medium">Uso CFDI</p>
|
||||||
<p className="text-sm font-medium text-gray-700 mt-1">
|
<p className="text-sm font-medium text-gray-700 mt-1">
|
||||||
{cfdi.usoCfdi} - {usoCfdiLabels[cfdi.usoCfdi] || ''}
|
{cfdi.usoCfdi} - {usoCfdiLabels[cfdi.usoCfdi] || ''}
|
||||||
@@ -158,6 +204,41 @@ export const CfdiInvoice = forwardRef<HTMLDivElement, CfdiInvoiceProps>(
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* CFDIs Relacionados */}
|
||||||
|
{(cfdi.cfdiTipoRelacion || cfdi.cfdisRelacionados) && (
|
||||||
|
<div className="bg-amber-50 rounded-lg p-3 mb-5 border border-amber-200">
|
||||||
|
<div className="flex items-start gap-3">
|
||||||
|
<svg className="w-5 h-5 text-amber-600 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
||||||
|
</svg>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<p className="text-xs font-semibold text-amber-800 uppercase tracking-wide">CFDI Relacionado</p>
|
||||||
|
{cfdi.cfdiTipoRelacion && (
|
||||||
|
<p className="text-sm text-gray-700 mt-1">
|
||||||
|
<span className="font-medium">Tipo de relación:</span>{' '}
|
||||||
|
{cfdi.cfdiTipoRelacion} — {tipoRelacionLabels[cfdi.cfdiTipoRelacion] || 'Desconocido'}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{cfdi.cfdisRelacionados && (
|
||||||
|
<div className="text-sm text-gray-700 mt-1">
|
||||||
|
<span className="font-medium">UUIDs relacionados:</span>
|
||||||
|
<div className="flex flex-wrap gap-2 mt-1">
|
||||||
|
{cfdi.cfdisRelacionados.split('|').map((uuid) => uuid.trim()).filter(Boolean).map((uuid, idx) => (
|
||||||
|
<span
|
||||||
|
key={idx}
|
||||||
|
className="inline-block px-2 py-0.5 bg-white border border-amber-200 rounded text-xs font-mono text-gray-600"
|
||||||
|
>
|
||||||
|
{uuid}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Datos del Comprobante */}
|
{/* Datos del Comprobante */}
|
||||||
<div className="grid grid-cols-4 gap-3 mb-5">
|
<div className="grid grid-cols-4 gap-3 mb-5">
|
||||||
<div className="bg-gray-50 rounded-lg p-3 text-center">
|
<div className="bg-gray-50 rounded-lg p-3 text-center">
|
||||||
@@ -203,6 +284,7 @@ export const CfdiInvoice = forwardRef<HTMLDivElement, CfdiInvoiceProps>(
|
|||||||
<thead>
|
<thead>
|
||||||
<tr className="bg-gray-100">
|
<tr className="bg-gray-100">
|
||||||
<th className="text-left py-3 px-4 font-semibold text-gray-700">Descripción</th>
|
<th className="text-left py-3 px-4 font-semibold text-gray-700">Descripción</th>
|
||||||
|
<th className="text-center py-3 px-3 font-semibold text-gray-700 w-24">No. Id.</th>
|
||||||
<th className="text-center py-3 px-3 font-semibold text-gray-700 w-20">Cant.</th>
|
<th className="text-center py-3 px-3 font-semibold text-gray-700 w-20">Cant.</th>
|
||||||
<th className="text-right py-3 px-4 font-semibold text-gray-700 w-32">P. Unitario</th>
|
<th className="text-right py-3 px-4 font-semibold text-gray-700 w-32">P. Unitario</th>
|
||||||
<th className="text-right py-3 px-4 font-semibold text-gray-700 w-32">Importe</th>
|
<th className="text-right py-3 px-4 font-semibold text-gray-700 w-32">Importe</th>
|
||||||
@@ -223,6 +305,9 @@ export const CfdiInvoice = forwardRef<HTMLDivElement, CfdiInvoiceProps>(
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</td>
|
</td>
|
||||||
|
<td className="text-center py-3 px-3 text-gray-700">
|
||||||
|
{concepto.noIdentificacion || <span className="text-gray-300">—</span>}
|
||||||
|
</td>
|
||||||
<td className="text-center py-3 px-3 text-gray-700">{concepto.cantidad}</td>
|
<td className="text-center py-3 px-3 text-gray-700">{concepto.cantidad}</td>
|
||||||
<td className="text-right py-3 px-4 text-gray-700">
|
<td className="text-right py-3 px-4 text-gray-700">
|
||||||
{formatCurrency(concepto.valorUnitario)}
|
{formatCurrency(concepto.valorUnitario)}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ interface CfdiConcepto {
|
|||||||
importe: number;
|
importe: number;
|
||||||
claveProdServ?: string;
|
claveProdServ?: string;
|
||||||
claveUnidad?: string;
|
claveUnidad?: string;
|
||||||
|
noIdentificacion?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CfdiViewerModalProps {
|
interface CfdiViewerModalProps {
|
||||||
@@ -39,6 +40,7 @@ function parseConceptosFromXml(xmlString: string): CfdiConcepto[] {
|
|||||||
importe: parseFloat(el.getAttribute('Importe') || '0'),
|
importe: parseFloat(el.getAttribute('Importe') || '0'),
|
||||||
claveProdServ: el.getAttribute('ClaveProdServ') || undefined,
|
claveProdServ: el.getAttribute('ClaveProdServ') || undefined,
|
||||||
claveUnidad: el.getAttribute('ClaveUnidad') || undefined,
|
claveUnidad: el.getAttribute('ClaveUnidad') || undefined,
|
||||||
|
noIdentificacion: el.getAttribute('NoIdentificacion') || undefined,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +77,7 @@ export function CfdiViewerModal({ cfdi, open, onClose }: CfdiViewerModalProps) {
|
|||||||
importe: Number(c.importe),
|
importe: Number(c.importe),
|
||||||
claveProdServ: c.claveProdServ || undefined,
|
claveProdServ: c.claveProdServ || undefined,
|
||||||
claveUnidad: c.claveUnidad || undefined,
|
claveUnidad: c.claveUnidad || undefined,
|
||||||
|
noIdentificacion: c.noIdentificacion || undefined,
|
||||||
})));
|
})));
|
||||||
} else if (cfdi.xmlOriginal) {
|
} else if (cfdi.xmlOriginal) {
|
||||||
setConceptos(parseConceptosFromXml(cfdi.xmlOriginal));
|
setConceptos(parseConceptosFromXml(cfdi.xmlOriginal));
|
||||||
|
|||||||
@@ -390,3 +390,42 @@ Se reemplazó por un estado de resultados vertical contable con 7 líneas, anál
|
|||||||
**Causa:** PostgreSQL devolvía `numeric` como string en el driver `pg`. Al sumar strings en el `reduce` del frontend, JavaScript concatenaba en lugar de sumar, generando `NaN` al formatear.
|
**Causa:** PostgreSQL devolvía `numeric` como string en el driver `pg`. Al sumar strings en el `reduce` del frontend, JavaScript concatenaba en lugar de sumar, generando `NaN` al formatear.
|
||||||
|
|
||||||
**Fix:** Se agregó `::float` en las 5 queries SQL de CFDIs individuales del drill-down, forzando que el backend devuelva números reales.
|
**Fix:** Se agregó `::float` en las 5 queries SQL de CFDIs individuales del drill-down, forzando que el backend devuelva números reales.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Visualizador de CFDI — campos faltantes
|
||||||
|
|
||||||
|
**Fecha:** 2026-05-04
|
||||||
|
|
||||||
|
Se agregaron 5 campos adicionales al visualizador de CFDI (`CfdiInvoice`) para mostrar información completa del comprobante:
|
||||||
|
|
||||||
|
| Campo | Origen | Backend | Frontend |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **C.P. del receptor** | CFDI 4.0 `Receptor@DomicilioFiscalReceptor` | ✅ Migración + parser + sync + query | ✅ Tarjeta de receptor |
|
||||||
|
| **Régimen del receptor** | Ya existía en BD | — | ✅ Tarjeta de receptor con descripción |
|
||||||
|
| **No. identificación** (conceptos) | Ya existía en BD | — | ✅ Nueva columna en tabla de conceptos |
|
||||||
|
| **Tipo de relación** | Ya existía en BD | — | ✅ Sección "CFDI Relacionado" con descripción SAT |
|
||||||
|
| **CFDIs relacionados** (UUIDs) | Ya existía en BD | — | ✅ Badges con UUIDs separados por pipe |
|
||||||
|
|
||||||
|
### Backend (`apps/api/`)
|
||||||
|
|
||||||
|
| Archivo | Cambio |
|
||||||
|
|---|---|
|
||||||
|
| `src/migrations/tenant/044_cfdis_codigo_postal_receptor.sql` | Nueva migración: columna `codigo_postal_receptor VARCHAR(5)` + índice parcial |
|
||||||
|
| `src/services/sat/sat-parser.service.ts` | Extrae `codigoPostalReceptor` de `@_DomicilioFiscalReceptor` |
|
||||||
|
| `src/services/sat/sat.service.ts` | INSERT/UPDATE incluyen `codigo_postal_receptor` |
|
||||||
|
| `src/services/cfdi.service.ts` | `CFDI_SELECT` mapea `codigo_postal_receptor` → `"codigoPostalReceptor"` |
|
||||||
|
| `packages/shared/src/types/cfdi.ts` | Agregado `codigoPostalReceptor: string \| null` a interfaz `Cfdi` |
|
||||||
|
|
||||||
|
### Frontend (`apps/web/`)
|
||||||
|
|
||||||
|
| Archivo | Cambio |
|
||||||
|
|---|---|
|
||||||
|
| `components/cfdi/cfdi-invoice.tsx` | Renderizado de C.P., régimen, tipo relación, UUIDs relacionados, y columna "No. Id." en conceptos |
|
||||||
|
| `components/cfdi/cfdi-viewer-modal.tsx` | Mapea `noIdentificacion` desde DB y desde parseo XML |
|
||||||
|
|
||||||
|
### Diccionarios agregados
|
||||||
|
|
||||||
|
- **`regimenFiscalLabels`**: 20 regímenes fiscales (601–626)
|
||||||
|
- **`tipoRelacionLabels`**: 7 tipos de relación SAT (`01` Nota de crédito … `07` Aplicación de anticipo)
|
||||||
|
- **`usoCfdiLabels`**: ya existía, se reutiliza para el receptor
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ export interface Cfdi {
|
|||||||
// Régimen fiscal
|
// Régimen fiscal
|
||||||
regimenFiscalEmisor: string | null;
|
regimenFiscalEmisor: string | null;
|
||||||
regimenFiscalReceptor: string | null;
|
regimenFiscalReceptor: string | null;
|
||||||
|
codigoPostalReceptor: string | null;
|
||||||
// FK a tabla rfcs
|
// FK a tabla rfcs
|
||||||
rfcEmisorId: number | null;
|
rfcEmisorId: number | null;
|
||||||
rfcReceptorId: number | null;
|
rfcReceptorId: number | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user