233 lines
8.1 KiB
Markdown
233 lines
8.1 KiB
Markdown
# Sprint 5: CFDI/Facturación - Resumen
|
|
|
|
## Objetivo
|
|
Implementar el sistema completo de facturación electrónica CFDI 4.0 para el vertical de Retail, con integración a PACs y soporte para autofactura.
|
|
|
|
## Componentes Implementados
|
|
|
|
### 1. Servicios
|
|
|
|
#### XMLService (`src/modules/invoicing/services/xml.service.ts`)
|
|
Servicio para construcción y manipulación de XML CFDI 4.0:
|
|
|
|
- **buildCFDIXML()**: Construye XML completo según especificación SAT
|
|
- **addSealToXML()**: Agrega sello del contribuyente
|
|
- **addCertificateToXML()**: Agrega certificado CSD
|
|
- **addTimbreToXML()**: Agrega complemento TimbreFiscalDigital
|
|
- **buildCadenaOriginal()**: Genera cadena original para firma
|
|
- **parseStampedXML()**: Parsea respuesta de PAC
|
|
- **generateQRData()**: Genera URL de verificación SAT para QR
|
|
- **validateXMLStructure()**: Validación básica de estructura
|
|
|
|
**Características:**
|
|
- Namespaces CFDI 4.0 y TFD 1.1
|
|
- Soporte para CFDIs relacionados
|
|
- Formateo de montos y tasas según SAT
|
|
- Generación de cadena original del SAT
|
|
|
|
#### PACService (`src/modules/invoicing/services/pac.service.ts`)
|
|
Servicio de integración con Proveedores Autorizados de Certificación:
|
|
|
|
- **stampCFDI()**: Timbrado de CFDI
|
|
- **cancelCFDI()**: Cancelación con motivo
|
|
- **verifyCFDIStatus()**: Consulta estado en SAT
|
|
- **encrypt()/decrypt()**: Cifrado de credenciales
|
|
- **loadCertificate()**: Carga de CSD
|
|
- **signData()**: Firma con llave privada
|
|
|
|
**PACs Soportados:**
|
|
| PAC | Timbrado | Cancelación | Verificación |
|
|
|-----|----------|-------------|--------------|
|
|
| Finkok | ✓ | ✓ | ✓ |
|
|
| Facturapi | ✓ | ✓ | - |
|
|
| SW Sapien | ✓ | - | - |
|
|
| Soluciones Fiscales | Config | Config | Config |
|
|
| Digisat | Config | Config | Config |
|
|
|
|
**Motivos de Cancelación (SAT):**
|
|
- `01`: Comprobante emitido con errores con relación
|
|
- `02`: Comprobante emitido con errores sin relación
|
|
- `03`: No se llevó a cabo la operación
|
|
- `04`: Operación nominativa relacionada en factura global
|
|
|
|
#### CFDIBuilderService (`src/modules/invoicing/services/cfdi-builder.service.ts`)
|
|
Constructor de estructuras CFDI desde datos de orden:
|
|
|
|
- **buildFromOrder()**: Construye CFDI desde líneas de pedido
|
|
- **buildCreditNote()**: Genera nota de crédito
|
|
- **buildPaymentComplement()**: Genera complemento de pago
|
|
- **validateReceptor()**: Valida datos del receptor (CFDI 4.0)
|
|
- **getUsoCFDIOptions()**: Opciones de uso CFDI por tipo de persona
|
|
- **getCommonClavesProdServ()**: Claves SAT comunes para retail
|
|
|
|
**Cálculos Automáticos:**
|
|
- Desglose de impuestos (IVA, ISR, IEPS)
|
|
- Agregación por tipo de impuesto
|
|
- Manejo de precios con/sin impuesto
|
|
- Retenciones IVA e ISR
|
|
|
|
#### CFDIService (`src/modules/invoicing/services/cfdi.service.ts`)
|
|
Servicio principal de facturación:
|
|
|
|
- **createCFDI()**: Crear factura (draft o timbrada)
|
|
- **stampCFDI()**: Timbrar factura en borrador
|
|
- **cancelCFDI()**: Cancelar factura timbrada
|
|
- **verifyCFDIStatus()**: Verificar estado en SAT
|
|
- **listCFDIs()**: Listado con filtros paginados
|
|
- **getCFDIById()**: Obtener por ID
|
|
- **getCFDIByUUID()**: Obtener por UUID
|
|
- **downloadXML()**: Descargar XML
|
|
- **resendEmail()**: Reenviar por correo
|
|
- **createCreditNote()**: Crear nota de crédito
|
|
- **getStats()**: Estadísticas de facturación
|
|
- **getActiveConfig()**: Obtener configuración activa
|
|
|
|
### 2. Validación Zod (`src/modules/invoicing/validation/cfdi.schema.ts`)
|
|
|
|
**Schemas de CFDI:**
|
|
- `receptorSchema`: Datos del receptor con validación RFC
|
|
- `orderLineSchema`: Líneas con claves SAT
|
|
- `createCFDISchema`: Creación completa
|
|
- `cancelCFDISchema`: Cancelación con motivo
|
|
- `listCFDIsQuerySchema`: Filtros de búsqueda
|
|
- `createCreditNoteSchema`: Nota de crédito
|
|
|
|
**Schemas de Configuración:**
|
|
- `createCFDIConfigSchema`: Configuración PAC y CSD
|
|
- `updateCFDIConfigSchema`: Actualización parcial
|
|
- `validateCFDIConfigSchema`: Validación de config
|
|
|
|
**Schemas de Autofactura:**
|
|
- `autofacturaRequestSchema`: Solicitud de autofactura
|
|
- `lookupOrderSchema`: Búsqueda de ticket
|
|
|
|
### 3. Controladores (`src/modules/invoicing/controllers/cfdi.controller.ts`)
|
|
|
|
**Endpoints de CFDI (14):**
|
|
| Método | Ruta | Descripción |
|
|
|--------|------|-------------|
|
|
| GET | `/cfdis` | Listar CFDIs |
|
|
| GET | `/cfdis/:id` | Obtener por ID |
|
|
| GET | `/cfdis/uuid/:uuid` | Obtener por UUID |
|
|
| POST | `/cfdis` | Crear CFDI |
|
|
| POST | `/cfdis/:id/stamp` | Timbrar |
|
|
| POST | `/cfdis/:id/cancel` | Cancelar |
|
|
| GET | `/cfdis/:id/verify` | Verificar en SAT |
|
|
| GET | `/cfdis/:id/xml` | Descargar XML |
|
|
| POST | `/cfdis/:id/resend-email` | Reenviar email |
|
|
| POST | `/cfdis/:id/credit-note` | Crear nota crédito |
|
|
| GET | `/stats` | Estadísticas |
|
|
| GET | `/cancellation-reasons` | Motivos cancelación |
|
|
| GET | `/uso-cfdi-options` | Opciones UsoCFDI |
|
|
| GET | `/claves-prod-serv` | Claves SAT |
|
|
|
|
**Endpoints de Configuración (5):**
|
|
| Método | Ruta | Descripción |
|
|
|--------|------|-------------|
|
|
| GET | `/config` | Obtener config |
|
|
| POST | `/config` | Crear/actualizar config |
|
|
| PUT | `/config` | Actualizar config |
|
|
| POST | `/config/certificate` | Subir CSD |
|
|
| POST | `/config/validate` | Validar config |
|
|
|
|
**Endpoints de Autofactura (2):**
|
|
| Método | Ruta | Descripción |
|
|
|--------|------|-------------|
|
|
| POST | `/autofactura/lookup` | Buscar ticket |
|
|
| POST | `/autofactura/create` | Generar factura |
|
|
|
|
**Total: 21 endpoints**
|
|
|
|
### 4. Rutas (`src/modules/invoicing/routes/cfdi.routes.ts`)
|
|
|
|
**Rutas Públicas:**
|
|
- Autofactura (lookup, create)
|
|
- Catálogos SAT (uso CFDI, claves prod/serv, motivos cancelación)
|
|
|
|
**Rutas Autenticadas:**
|
|
- CFDI CRUD y operaciones
|
|
- Configuración (requiere `cfdi:config:*`)
|
|
|
|
**Permisos Requeridos:**
|
|
- `cfdi:view`, `cfdi:create`, `cfdi:stamp`, `cfdi:cancel`, `cfdi:send`
|
|
- `cfdi:config:view`, `cfdi:config:manage`
|
|
|
|
## Estructura de Archivos
|
|
|
|
```
|
|
src/modules/invoicing/
|
|
├── controllers/
|
|
│ ├── index.ts
|
|
│ └── cfdi.controller.ts
|
|
├── entities/
|
|
│ ├── index.ts
|
|
│ ├── cfdi.entity.ts
|
|
│ └── cfdi-config.entity.ts
|
|
├── routes/
|
|
│ ├── index.ts
|
|
│ └── cfdi.routes.ts
|
|
├── services/
|
|
│ ├── index.ts
|
|
│ ├── cfdi.service.ts
|
|
│ ├── cfdi-builder.service.ts
|
|
│ ├── xml.service.ts
|
|
│ └── pac.service.ts
|
|
├── validation/
|
|
│ ├── index.ts
|
|
│ └── cfdi.schema.ts
|
|
└── index.ts
|
|
```
|
|
|
|
## Flujo de Facturación
|
|
|
|
```
|
|
┌────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
│ Order │────▶│ CFDIBuilder │────▶│ CFDI │
|
|
│ Data │ │ Service │ │ (draft) │
|
|
└────────────┘ └──────────────┘ └──────┬──────┘
|
|
│
|
|
▼
|
|
┌────────────┐ ┌──────────────┐ ┌─────────────┐
|
|
│ Stamped │◀────│ PAC │◀────│ XML │
|
|
│ CFDI │ │ Service │ │ Service │
|
|
└────────────┘ └──────────────┘ └─────────────┘
|
|
```
|
|
|
|
## Estados del CFDI
|
|
|
|
```
|
|
draft ──────▶ pending ──────▶ stamped ──────▶ cancelled
|
|
│ │
|
|
▼ ▼
|
|
error cancellation_pending
|
|
```
|
|
|
|
## Características CFDI 4.0
|
|
|
|
- Validación de RFC y régimen fiscal del receptor
|
|
- Código postal del domicilio fiscal requerido
|
|
- Objeto de impuesto por concepto
|
|
- Relacionados con tipo de relación
|
|
- Exportación (01 = No exportación)
|
|
|
|
## Dependencias
|
|
|
|
- xmlbuilder2: Construcción de XML
|
|
- crypto (Node.js): Cifrado y firma
|
|
- TypeORM 0.3.x
|
|
- Zod para validación
|
|
|
|
## Variables de Entorno Requeridas
|
|
|
|
```env
|
|
PAC_ENCRYPTION_KEY=your-32-byte-encryption-key
|
|
```
|
|
|
|
## Próximos Pasos
|
|
|
|
El Sprint 6 según el roadmap cubrirá POS Backend:
|
|
- Sesiones de POS
|
|
- Órdenes y líneas
|
|
- Pagos múltiples
|
|
- Integración con motor de precios
|