🤖 RPA: Generación automática de facturas en PDF

Este proyecto demuestra cómo automatizar la generación de facturas con Python a partir de datos estructurados (CSV/Excel/BD). El robot lee los pedidos, compone la factura (cabecera, líneas, impuestos, totales), genera un PDF y opcionalmente lo envía por email.

📥 Entradas

  • Datos de cliente y pedido (CSV / Excel / BD).
  • Items: descripción, cantidad, precio, impuestos.
  • Plantilla de numeración y fechas.

📤 Salidas

  • Factura PDF con logo, cabecera, tabla de líneas y totales.
  • Registro en logs (estado/errores).
  • Opcional: envío por email o subida a carpeta/NAS.

🛠️ Stack

  • Python (automatización del flujo).
  • pandas (lectura/transformación de datos).
  • FPDF/ReportLab (generación PDF).
  • logging (trazas) y schedule/cron (planificación).

🗺️ Flujo de alto nivel

  1. Leer fuente de datos (CSV/Excel/BD) con pedidos pendientes.
  2. Para cada pedido: componer cabecera (cliente, fecha, nº factura) y líneas.
  3. Calcular base imponible, IVA/IGIC y total.
  4. Generar PDF con logotipo, tabla y totales; guardar con nomenclatura consistente.
  5. Actualizar estado y (opcional) enviar por email o subir a carpeta.

📑 Ejemplo de código (PDF con FPDF)

from fpdf import FPDF
import pandas as pd
from datetime import datetime

# Cargar datos (ajusta ruta/columnas)
df = pd.read_csv("pedidos.csv")  # id, cliente, direccion, fecha, item, qty, precio, iva

class FacturaPDF(FPDF):
    def header(self):
        # Logo (opcional)
        # self.image("logo.png", 10, 8, 30)
        self.set_font("Helvetica", "B", 14)
        self.cell(0, 10, "FACTURA", 0, 1, "R")
        self.ln(2)

    def footer(self):
        self.set_y(-12)
        self.set_font("Helvetica", "I", 9)
        self.cell(0, 10, f"Página {self.page_no()}", 0, 0, "C")

def generar_factura(pedido_id, items):
    pdf = FacturaPDF()
    pdf.add_page()
    pdf.set_auto_page_break(auto=True, margin=15)

    # Cabecera de factura
    pedido = items.iloc[0]
    pdf.set_font("Helvetica", "", 11)
    pdf.cell(0, 6, f"Factura Nº: {pedido_id}", 0, 1)
    pdf.cell(0, 6, f"Fecha: {datetime.now():%Y-%m-%d}", 0, 1)
    pdf.cell(0, 6, f"Cliente: {pedido['cliente']}", 0, 1)
    pdf.cell(0, 6, f"Dirección: {pedido['direccion']}", 0, 1)
    pdf.ln(4)

    # Tabla
    pdf.set_font("Helvetica", "B", 11)
    col_w = [90, 20, 30, 30]  # desc, qty, precio, total
    headers = ["Descripción", "Qty", "Precio", "Total"]
    for w, h in zip(col_w, headers):
        pdf.cell(w, 8, h, 1, 0, "C")
    pdf.ln(8)

    pdf.set_font("Helvetica", "", 11)
    base = 0.0
    for _, r in items.iterrows():
        total_linea = r["qty"] * r["precio"]
        base += total_linea
        pdf.cell(col_w[0], 8, str(r["item"]), 1)
        pdf.cell(col_w[1], 8, str(r["qty"]), 1, 0, "C")
        pdf.cell(col_w[2], 8, f"{r['precio']:.2f} €", 1, 0, "R")
        pdf.cell(col_w[3], 8, f"{total_linea:.2f} €", 1, 1, "R")

    iva_pct = items.iloc[0].get("iva", 21)
    iva = base * iva_pct/100
    total = base + iva

    pdf.ln(2)
    pdf.cell(0, 6, f"Base imponible: {base:.2f} €", 0, 1, "R")
    pdf.cell(0, 6, f"IVA ({iva_pct}%): {iva:.2f} €", 0, 1, "R")
    pdf.set_font("Helvetica", "B", 12)
    pdf.cell(0, 8, f"TOTAL: {total:.2f} €", 0, 1, "R")

    # Guardar
    out = f"facturas/FACT_{pedido_id}.pdf"
    pdf.output(out)
    return out

# Agrupar por pedido_id
for pedido_id, group in df.groupby("id"):
    ruta_pdf = generar_factura(pedido_id, group)
    print("Generada:", ruta_pdf)

⏱️ Planificación y envío (opcional)

  • Planifica la ejecución con schedule (Windows Task Scheduler) o cron (Linux).
  • Envía el PDF por email con smtplib o integra una API de tu ERP/CRM.
  • Registra eventos/errores con logging para auditoría.

✅ Buenas prácticas

  • Control de errores y reintentos en lectura de ficheros y escritura de PDFs.
  • Separar plantilla (logo, empresa, estilos) de la lógica del robot.
  • Validar datos de entrada: tipos, rangos, campos obligatorios.
  • Versionar el robot y parametrizar rutas/IVA/moneda.
Todos los derechos reservados © | Política de Privacidad | Política de Cookies
Scroll al inicio