LEFA genera documentos PDF de forma nativa usando la biblioteca FPDF2, sin dependencias de navegador ni LaTeX. El móduloDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/entreunosyceros/lefa/llms.txt
Use this file to discover all available pages before exploring further.
PDFService gestiona los PDFs de facturas —incluyendo el código QR tributario exigido por la normativa VeriFactu— mientras que PresupuestoPDFService produce los PDFs de presupuestos, más sencillos al no requerir QR ni registro fiscal. Ambos servicios leen las preferencias del emisor (razón social, CIF, dirección, IBAN, logotipo y pie de página) en tiempo de generación, por lo que cualquier cambio en las preferencias se refleja en el siguiente PDF generado. La generación se delega en hilos de fondo (pdf_worker.py y presupuesto_pdf_worker.py) para no bloquear la interfaz PyQt6.
Directorios de salida
| Servicio | Directorio por defecto |
|---|---|
PDFService (facturas) | ~/.lefa/facturas_pdf/ |
PresupuestoPDFService (presupuestos) | ~/.lefa/presupuestos_pdf/ |
ensure_directories() al inicio de cada método generar.
PDFService
Construye documentos PDF profesionales a partir de un objeto Factura ORM. El renderizado es completamente nativo con fuentes Helvetica (fuente core de FPDF2) con normalización de caracteres Unicode problemáticos (em-dash, en-dash, signo menos) para garantizar compatibilidad.
generar
- Borrador:
BORRADOR_{id}.pdf - Emitida / Cobrada:
{numero_factura}.pdf(con/sustituido por-)
- Código QR tributario (35 × 35 mm, esquina superior derecha) — solo en facturas emitidas con número y fecha. Contiene la URL de verificación AEAT construida por
url_verificacion(). La imagen PNG temporal se genera y elimina automáticamente. - Leyenda legal junto al QR (
VERI*FACTUoSISTEMA INFORMÁTICO NO VERIFICADOsegún el modo configurado). - Logotipo del emisor (esquina superior izquierda), leído de las preferencias. Si no existe el archivo, se omite sin error.
- Cabecera del emisor: razón social, CIF, dirección, teléfono, email e IBAN.
- Bloque de datos de la factura (número, fechas, estado) y del cliente (razón social, NIF, dirección, email).
- Aviso de factura rectificativa (en rojo) con número y fecha de la factura original, si aplica.
- Tabla de líneas con columnas Descripción, Cantidad, Precio Unit. y Subtotal.
- Bloque de totales: subtotal, IVA, IRPF y TOTAL en la columna derecha.
- Marca de agua de borrador en gris itálico, solo en borradores.
- Pie de página personalizado leído de las preferencias, si está configurado.
Objeto
Factura ORM con las relaciones cliente, lineas y (si es rectificativa) factura_rectificada ya cargadas.Path del archivo PDF generado.
ruta_pdf_factura
Objeto
Factura del que se desea conocer la ruta.Path a ~/.lefa/facturas_pdf/{nombre}.pdf.
obtener_o_generar
generar. Evita regenerar el PDF en cada apertura desde la UI.
Objeto
Factura ORM.Path al archivo PDF (existente o recién generado).
_texto_pdf_safe (privado)
—, en-dash –, signo menos −) sustituyéndolos por guiones ASCII. Se aplica automáticamente al pie de página y a otros campos de texto libre.
PresupuestoPDFService
Genera PDFs de presupuestos sin QR tributario ni información fiscal. La estructura es idéntica a la de las facturas pero más compacta, con el bloque de validez en lugar del vencimiento y sin los campos de rectificación.
generar
~/.lefa/presupuestos_pdf/. El nombre del archivo sigue el mismo patrón que las facturas:
- Borrador:
PRES_BORRADOR_{id}.pdf - Emitido / Aceptado / Convertido:
{numero_presupuesto}.pdf(con/sustituido por-)
- Logotipo del emisor (si existe).
- Cabecera del emisor: razón social, CIF, dirección y email.
- Bloque de datos del presupuesto: número, fecha, válido hasta, y datos del cliente.
- Tabla de líneas con las mismas columnas que la factura.
- Bloque de totales: subtotal, IVA, IRPF y TOTAL.
- Marca de borrador en gris itálico, si el presupuesto está en estado
BORRADOR. - Nota informativa fija: «Este documento es un presupuesto informativo. No sustituye a una factura.»
Objeto
Presupuesto ORM con las relaciones cliente y lineas ya cargadas.Path del archivo PDF generado.
Workers de generación en segundo plano
Para no bloquear la interfaz de usuario PyQt6, la generación de PDF se ejecuta siempre en un hilo secundario mediante dos workers dedicados:| Clase worker | Servicio que invoca | finished_ok emite | finished_error emite |
|---|---|---|---|
PDFWorker | PDFService.generar | dict con claves pdf (Path) y xml (Path o None) | str con el mensaje de error |
PresupuestoPDFWorker | PresupuestoPDFService.generar | Path del PDF generado | str con el mensaje de error |
QThread y emiten la señal finished_ok cuando la generación concluye con éxito, o finished_error si se produce una excepción. La ventana principal conecta estas señales para abrir el visor del sistema operativo de forma automática tras la generación.
Ejemplo de uso
El QR tributario solo se incrusta en facturas con
numero_factura y fecha_emision asignados (es decir, facturas emitidas). Los borradores generan un PDF sin QR y con la marca de agua «DOCUMENTO EN BORRADOR - Sin validez fiscal».