Flujos de trabajo
Esta página reúne los flujos de trabajo principales en formato de diagrama para facilitar la comprensión del ciclo de vida completo de un comprobante fiscal electrónico.
Flujo completo de emisión de un CFE
Section titled “Flujo completo de emisión de un CFE”Desde la configuración inicial hasta obtener el PDF listo para entregar al cliente.
flowchart TD
A([Inicio]) --> B[new UruFacturaClient config\nvalida la config y carga el certificado]
B --> C[RegistrarCaeAsync\nuna vez por CAE]
C --> G[Describir el comprobante\nnew Cfe tipo · Detalle · Receptor · Referencias]
G --> H[EmitirAsync]
H --> V{¿Válido y hay CAE?}
V -- No --> X[❌ CfeValidationException o CaeException\nno se consume ningún número]
V -- Sí --> E[CfeEmitido\nnúmero · XML firmado · totales · QR]
E --> K[EnviarAsync\nsobre EnvioCFE + SOAP/WS-Security]
K --> L{Acuse del sobre}
L -- AS\nrecibido --> L2[ConsultarEnvioAsync acuse]
L -- BS / BA\nrechazado --> N[❌ Revisar acuse.Mensaje\ny reenviar el mismo CfeEmitido]
L2 -- AE\naceptado --> M[✅ emitido.AceptadoPorDgi]
L2 -- BE / CE --> N2[❌ emitido.MensajeDgi]
M --> O[CfePdf.GenerarA4 / GenerarTermico]
O --> Q([Fin])
Pipeline interno de EmitirAsync y EnviarAsync
Section titled “Pipeline interno de EmitirAsync y EnviarAsync”sequenceDiagram participant App as Tu aplicación participant Client as UruFacturaClient participant Store as IUruFacturaStore participant DGI as DGI (SOAP) App->>Client: EmitirAsync(cfe) Note over Client: Valida el contenido y copia sus listas Client->>Store: ListarCaesAsync() Note over Client: Elige el CAE vigente y el próximo número,<br/>arma el XML, calcula totales y firma Client->>Store: RegistrarEmisionAsync(emitido, último número leído) Note over Store: Avanza el CAE y guarda el CFE en una transacción.<br/>Si otra emisión usó el número: no guarda nada y se renumera Client-->>App: CfeEmitido App->>Client: EnviarAsync(emitido) Client->>Store: ReservarIdEnvioAsync() Client->>DGI: EFACRECEPCIONSOBRE (sobre EnvioCFE, WS-Security) DGI-->>Client: ACKSobre (AS/BS, IdReceptor, Token) Client->>Store: GuardarCfesAsync (IdReceptor y Token) Client-->>App: AcuseSobre
Flujo de firma digital
Section titled “Flujo de firma digital”flowchart LR A[CFE validado y numerado] --> B[Serializar a XML\nesquema DGI] B --> C[Calcular digest\nSHA-256 / SHA-1] C --> D[Construir SignedInfo\nC14N · enveloped-signature] D --> E[Firmar SignedInfo\ncon la clave privada] E --> F[Adjuntar certificado\nKeyInfo X509] F --> G[CfeEmitido.Xml\nCodigoSeguridad = DigestValue] G --> H[Sobre EnvioCFE\n+ SOAP firmado con WS-Security]
Ciclo de vida de un CAE
Section titled “Ciclo de vida de un CAE”stateDiagram-v2 [*] --> Registrado : RegistrarCaeAsync Registrado --> EnUso : EmitirAsync usa el primer número EnUso --> EnUso : EmitirAsync\n(UltimoNroUsado + 1) EnUso --> AdvertenciaRango : >= 80% del rango usado AdvertenciaRango --> Agotado : UltimoNroUsado = RangoHasta EnUso --> AdvertenciaVencimiento : <= 7 días para vencer AdvertenciaVencimiento --> Vencido : hoy > FechaVencimiento Agotado --> [*] : se usa el siguiente CAE vigente Vencido --> [*] : se usa el siguiente CAE vigente
Proceso de certificación DGI
Section titled “Proceso de certificación DGI”Pasos necesarios para pasar de cero a emitir en producción.
flowchart TD
A([Empresa sin habilitación]) --> B[1. Inscripción\nDGI en línea → Gestión CFE\n→ Inscripción como Emisor Electrónico]
B --> C{Aprobada?}
C -- No --> D[Esperar resolución DGI\ngeneralmente días hábiles]
D --> C
C -- Sí --> E[2. Obtener certificado digital\nABITAB · Correo Uruguayo · CertiSur\nFormato .p12/.pfx · vinculado al RUT]
E --> F[3. Solicitar CAE\nDGI en línea → Solicitud de CAE\nPor tipo de CFE y rango]
F --> G[4. Configurar SDK en Homologación\nAmbiente.Homologacion]
G --> H[5. Emitir y enviar CFEs de prueba\nEmitirAsync · EnviarAsync]
H --> I[6. Enviar Reporte Diario de prueba\nEnviarReporteDiarioAsync]
I --> J[7. Consultar estado de cada CFE\nConsultarEnvioAsync]
J --> K{Todo OK?}
K -- No --> L[Corregir errores\nrevisando respuesta.Mensaje]
L --> H
K -- Sí --> M[8. Notificar finalización\na DGI vía portal]
M --> N{DGI aprueba?}
N -- No --> O[Atender observaciones DGI]
O --> H
N -- Sí --> P[9. Cambiar a Producción\nAmbiente.Produccion]
P --> Q([✅ Habilitado para emitir en producción])
Flujo del Reporte Diario
Section titled “Flujo del Reporte Diario”DGI exige enviar un resumen de todos los CFE emitidos cada día.
flowchart TD
A([Fin de la jornada]) --> B{¿Se emitió\nalgún CFE hoy?}
B -- No --> C[No es obligatorio\npero recomendable enviar\nreporte vacío]
B -- Sí --> D[El almacenamiento tiene\nlos CFE emitidos del día]
D --> F[EnviarReporteDiarioAsync\nfecha]
F --> E[SDK resume por tipo de CFE\nmontos · cantidades · rangos]
E --> G[Arma ReporteDiarioCFE y lo firma\nno incluye los XML de los CFE]
G --> H[POST SOAP EFACRECEPCIONREPORTE]
H --> I{Respuesta DGI}
I -- AR\nrecibido --> J[✅ Reporte recibido\nArchivar confirmación]
I -- BR / BA\nrechazado --> K[❌ Reintentar\nrevisando respuesta.Mensaje]
K --> F
J --> L([Fin del día])
C --> L
Arquitectura de componentes
Section titled “Arquitectura de componentes”Las tres costuras públicas son el cliente, el almacenamiento y el transporte a la DGI. Todo lo demás (XML, firma, sobre, reporte) es interno.
classDiagram
direction LR
class IUruFacturaClient {
<<interface>>
+RegistrarCaeAsync(cae)
+EliminarCaeAsync(cae)
+Validar(cfe) ErrorValidacion
+EmitirAsync(cfe) CfeEmitido
+EnviarAsync(cfes) AcuseSobre
+ConsultarEnvioAsync(acuse) EstadoEnvio
+ConsultarCfeAsync(cfe) EstadoComprobante
+EnviarReporteDiarioAsync(fecha) AcuseReporte
}
class IUruFacturaStore {
<<interface>>
+GuardarCaeAsync(cae)
+ListarCaesAsync() Cae
+EliminarCaeAsync(cae) bool
+RegistrarEmisionAsync(emitido, ultimoLeido) bool
+ReservarIdEnvioAsync() long
+GuardarCfesAsync(cfes)
+BuscarCfesAsync(nroInterno)
+ListarCfesAsync(fecha)
}
class IDgiClient {
<<interface>>
+EnviarSobreAsync(xml) AcuseSobre
+ConsultarEnvioAsync(id, token) EstadoEnvio
+ConsultarCfeAsync(tipo, serie, nro) EstadoComprobante
+EnviarReporteAsync(xml) AcuseReporte
}
class CfePdf {
<<static>>
+GenerarA4(emitido) byte[]
+GenerarTermico(emitido) byte[]
}
IUruFacturaClient <|.. UruFacturaClient
UruFacturaClient --> IUruFacturaStore
UruFacturaClient --> IDgiClient
IUruFacturaStore <|.. InMemoryStore
IUruFacturaStore <|.. EfUruFacturaStore
IDgiClient <|.. DgiSoapClient : interno