Volver al Blog
Cloud Architecture RPA para PyMEs Siigo API Python Django Azure

Caso Ecolia: Cómo una PyME construyó un ERP de nivel mundial en Azure con Django y Siigo

Deep dive técnico: de hojas de Excel y correos dispersos a una plataforma cloud integrada. Arquitectura, decisiones de diseño, integración con la API de Siigo y resultados reales después de 8 meses en producción.

JC
Julian Chaparro · Software Architect & Data Scientist
12 min de lectura1 de mayo de 2026

Cuando Ecolia llegó a nosotros, su "sistema de gestión" era una carpeta compartida en Google Drive con 47 hojas de Excel. Cada área tenía la suya: ventas, contratos, inventario de equipos, nómina, reportes para clientes. La información nunca coincidía y nadie sabía cuál era la versión más reciente.

18 meses después, Ecolia opera sobre un ERP a medida construido en Azure App Service, con backend en Python/Django, base de datos SQL Server y sincronización contable automática con Siigo Nube. Este artículo documenta cada decisión técnica, los errores que cometimos y los resultados reales en producción.

1. El problema: gestionar una empresa en Excel

Ecolia es una empresa mediana de servicios ambientales con operaciones en tres ciudades colombianas. Con 80 empleados y más de 200 contratos activos, el modelo de "una hoja de Excel por proceso" había colapsado. Estos eran sus puntos de dolor concretos:

Doble digitación

El mismo pedido se registraba manualmente en 3 sistemas distintos: Excel de ventas, correo al bodeguero y luego en Siigo para facturar. 30 minutos por pedido.

Cierres contables de 5 días

El contador necesitaba 5 días para el cierre mensual porque los datos de ventas, gastos y nómina llegaban de fuentes distintas y no cuadraban.

Inventario fantasma

El inventario de equipos y materiales tenía un error promedio del 12%. Se descubrían faltantes solo cuando un técnico iba a despachar y no encontraba el equipo.

Sin trazabilidad de contratos

Era imposible responder en tiempo real preguntas como: ¿qué contratos vencen este mes? ¿qué proyectos tienen margen negativo? ¿qué cliente tiene cartera vencida?

El error más costoso: en Q3 2024, Ecolia facturó un proyecto por $18M COP usando un precio desactualizado en Excel. El contrato real era por $22M. La diferencia no se detectó hasta la auditoría interna 6 semanas después. Con el ERP, ese error es imposible: el precio siempre viene del maestro de productos bloqueado por rol.

2. La arquitectura: decisiones técnicas y por qué las tomamos

Antes de escribir una línea de código, pasamos 3 semanas en discovery: entrevistas con cada jefe de área, mapeo de flujos de datos y análisis de integraciones críticas. El resultado fue una arquitectura modular en Azure con un backend Django como núcleo.

┌─────────────────────────────────────────────────────────────┐ │ AZURE CLOUD (West US 2) │ │ │ │ ┌───────────────┐ ┌──────────────────┐ │ │ │ Azure App │ │ Azure SQL Server │ │ │ │ Service │───▶│ (SQL Server 2022)│ │ │ │ (Django API) │ │ + Backups auto │ │ │ └───────┬───────┘ └──────────────────┘ │ │ │ │ │ │ ┌──────────────────┐ │ │ ├───────────▶│ Azure Blob │ │ │ │ │ Storage │ │ │ │ │ (docs, PDFs) │ │ │ │ └──────────────────┘ │ │ │ │ │ │ ┌──────────────────┐ │ │ └───────────▶│ Azure Key Vault │ │ │ │ (secrets, creds)│ │ │ └──────────────────┘ │ └─────────────────────────────────────────────────────────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌──────────────────────┐ │ Next.js SPA │ │ Siigo Nube API │ │ (Frontend) │ │ (Facturación DIAN │ │ Azure SWA │ │ Contabilidad) │ └─────────────────┘ └──────────────────────┘ │ ▼ ┌─────────────────┐ │ Power Automate │ │ (RPA Flows) │ │ Notif. WhatsApp│ │ Reportes auto │ └─────────────────┘

¿Por qué Django y no Laravel, Node o un ERP off-the-shelf?

Evaluamos cuatro opciones: Odoo Community, SAP Business One, Laravel + Vue y Python Django + Next.js. La decisión de ir con Django no fue automática — fue el resultado de ponderar tres variables críticas para Ecolia:

  1. Velocidad de desarrollo: el ecosistema de Django (ORM, admin, DRF) permite construir módulos de negocio complejos en días, no semanas. Para una PyME con presupuesto ajustado, esto es determinante.
  2. Integración con Siigo: Siigo expone una API REST bien documentada. Django REST Framework simplifica la creación de la capa de sincronización bidireccional sin fricciones.
  3. Costo de mantenimiento: Python es el lenguaje más conocido por científicos de datos y automatizadores. El mismo equipo que mantiene el ERP puede crear scripts de RPA o modelos predictivos sin cambiar de stack.
Decisión de Cloud Architecture: optamos por Azure App Service en lugar de Azure Kubernetes Service (AKS) porque Ecolia tiene cargas predecibles. AKS tiene sentido para workloads con picos de tráfico masivos o microservicios independientes. Para este caso, App Service con auto-scaling es más económico y elimina la complejidad operativa de Kubernetes para un equipo interno sin DevOps dedicado.

3. Integración Siigo API: el núcleo contable automatizado

La integración con la API de Siigo Nube fue el componente más crítico del proyecto. El objetivo: eliminar la doble digitación contable. Cada factura generada en el ERP debía aparecer automáticamente en Siigo sin intervención humana, y cada pago registrado en Siigo debía actualizar el estado de la cuenta corriente en el ERP.

Flujo de autenticación y sincronización

python — siigo_client.py
import requests
from django.core.cache import cache
from django.conf import settings

class SiigoClient:
    """
    Cliente para la API REST de Siigo Nube.
    Gestiona tokens OAuth2 con renovación automática vía cache Django.
    """
    BASE_URL = "https://api.siigo.com/v1"
    TOKEN_KEY = "siigo_access_token"

    def _get_token(self) -> str:
        token = cache.get(self.TOKEN_KEY)
        if token:
            return token

        resp = requests.post(
            "https://api.siigo.com/auth/access-token",
            json={
                "partner_id": settings.SIIGO_PARTNER_ID,
                "username": settings.SIIGO_USERNAME,
                "access_key": settings.SIIGO_ACCESS_KEY,
            },
            timeout=10,
        )
        resp.raise_for_status()
        data = resp.json()
        # Siigo tokens duran 24 h; guardamos con TTL de 23 h para renovar antes
        cache.set(self.TOKEN_KEY, data["access_token"], timeout=82800)
        return data["access_token"]

    def _headers(self) -> dict:
        return {
            "Authorization": f"Bearer {self._get_token()}",
            "Content-Type": "application/json",
            "Partner-Id": settings.SIIGO_PARTNER_ID,
        }

    def create_invoice(self, invoice_data: dict) -> dict:
        """Crea una factura electrónica en Siigo desde los datos del ERP."""
        resp = requests.post(
            f"{self.BASE_URL}/invoices",
            json=invoice_data,
            headers=self._headers(),
            timeout=15,
        )
        resp.raise_for_status()
        return resp.json()

    def sync_payments(self, since: str) -> list:
        """Obtiene pagos registrados en Siigo desde una fecha dada."""
        resp = requests.get(
            f"{self.BASE_URL}/documents",
            params={"document_type": "FV", "date_start": since},
            headers=self._headers(),
            timeout=15,
        )
        resp.raise_for_status()
        return resp.json().get("results", [])

El modelo Django que representa una factura en el ERP tiene un camposiigo_id que almacena el ID retornado por la API de Siigo. Esto garantiza idempotencia: si la sincronización falla y se reintenta, no se crean duplicados.

python — models.py (fragmento)
class Factura(models.Model):
    numero          = models.CharField(max_length=20, unique=True)
    cliente         = models.ForeignKey("Cliente", on_delete=models.PROTECT)
    fecha_emision   = models.DateField()
    total_neto      = models.DecimalField(max_digits=14, decimal_places=2)
    total_iva       = models.DecimalField(max_digits=14, decimal_places=2)
    estado          = models.CharField(
        max_length=20,
        choices=[("borrador","Borrador"), ("emitida","Emitida"), ("pagada","Pagada")],
        default="borrador",
    )
    # Integración Siigo
    siigo_id        = models.CharField(max_length=60, blank=True, null=True, unique=True)
    siigo_synced_at = models.DateTimeField(null=True, blank=True)
    siigo_error     = models.TextField(blank=True)

    class Meta:
        ordering = ["-fecha_emision"]
        indexes  = [models.Index(fields=["estado", "siigo_id"])]
Resultado de la integración Siigo: el cierre contable mensual pasó de 5 días a 4 horas. El contador ahora solo revisa y aprueba — no digita. En 8 meses de producción, la sincronización automática procesó 1.847 facturas con una tasa de error del 0.3% (6 facturas con datos faltantes del usuario, no fallas de la API).

4. RPA para PyMEs: automatizar lo que el ERP no puede

El ERP centraliza los datos, pero hay procesos operativos que suceden fuera de él: notificaciones a clientes por WhatsApp, envío de reportes PDF a supervisores, alertas cuando un contrato está próximo a vencer. Para esto implementamos flujos de RPA con Power Automatesobre la capa de datos del ERP.

Alerta de vencimiento

30 días antes de vencer un contrato, el sistema envía un WhatsApp al gerente de cuenta con el resumen del cliente y un link para renovar.

Reporte diario de cartera

Cada mañana a las 7am, el bot genera el reporte de cartera vencida en PDF y lo envía por correo al gerente financiero y al director comercial.

Conciliación bancaria auto

El bot descarga el extracto bancario, lo compara contra los pagos registrados en Siigo y genera un reporte de diferencias. Proceso que tomaba 2 días ahora tarda 8 minutos.

La clave del éxito del RPA para PyMEs no está en la complejidad del bot — está en conectarlo a una fuente de datos limpia. Antes del ERP, automatizar estos flujos era imposible porque los datos estaban dispersos en hojas de cálculo sin estructura consistente. El ERP creó la base; el RPA la aprovecha.

5. La migración: cero downtime en una empresa en operación

El mayor riesgo de cualquier migración ERP no es técnico — es operativo. Ecolia no podía darse el lujo de parar operaciones ni un día. Nuestra estrategia fue un Big Bang controladocon rollback garantizado:

  1. 1
    Semanas 1-6 — Migración histórica silenciosa: importamos 3 años de datos (clientes, contratos, inventario) al nuevo sistema mientras Ecolia seguía operando en Excel. Validaciones automáticas diarias comparaban totales.
  2. 2
    Semana 7 — Modo paralelo (5 días): el equipo operaba simultáneamente en Excel y en el ERP. Cada transacción se registraba en ambos. Nos permitió detectar y corregir 23 inconsistencias.
  3. 3
    Semana 8 — Cutover en fin de semana: el sábado a las 11pm cerramos el Excel definitivamente. El ERP quedó como sistema único. El lunes el equipo llegó a trabajar en la nueva plataforma.
  4. 4
    Semanas 9-12 — Hypercare: un miembro de nuestro equipo estuvo disponible 8am-8pm para resolver dudas y ajustes. 147 tickets en 4 semanas; ninguno fue un bug crítico.

6. Resultados: 8 meses en producción

40%
Reducción OPEX
Menos horas-hombre en tareas administrativas
100%
Datos migrados
Sin pérdida de un solo registro histórico
150+
Usuarios activos
En 3 ciudades, sin degradación de rendimiento
<200ms
Tiempo de respuesta
P95 en producción bajo carga real
ProcesoAntesCon ERP + RPA
Registrar un pedido nuevo30 min3 min
Cierre contable mensual5 días4 horas
Conciliación bancaria2 días8 minutos (bot)
Reporte de cartera vencida1 díaAutomático 7am
Generar factura electrónica DIAN15 minInmediato (API Siigo)
Detectar contrato con margen negativoNunca / auditoríaAlerta en tiempo real
ROI calculado: Ecolia recuperó la inversión en el ERP en el mes 5 de producción. El ahorro mensual en horas-hombre (contabilidad, administración, reportes) supera el costo de mantenimiento de la plataforma por un factor de 3.2×.

7. Lecciones aprendidas

Después de 18 meses en este proyecto, estos son los principios que aplicaría en cualquier implementación ERP para PyME:

  • La calidad del dato es el proyecto. Podemos construir el mejor ERP del mundo, pero si los datos de partida están sucios, el ERP solo automatizará el caos. Dedicamos el 30% del presupuesto a limpieza y validación de datos históricos. Valió cada peso.
  • No construyas lo que ya existe bien. Siigo resuelve la contabilidad y la facturación DIAN mejor que cualquier módulo que podamos construir. Django resuelve la lógica de negocio de Ecolia. La integración entre ambos fue la decisión correcta — no reemplazar uno con el otro.
  • El RPA amplifica el ERP, no lo reemplaza. Power Automate conectado a la API del ERP automatizó en semanas procesos que habrían requerido meses de desarrollo custom. Para PyMEs, esta combinación es la relación costo/impacto más alta que encontramos.
  • Azure App Service es suficiente para el 80% de las PyMEs. No necesitas microservicios ni Kubernetes para una empresa de 80-300 empleados. App Service con auto-scaling y SQL Server managed cubren las necesidades con un costo operativo predecible y sin necesitar un DevOps interno.

¿Tu PyME todavía opera en Excel?

Podemos replicar la arquitectura de Ecolia adaptada a tu sector y operación. Agenda una sesión de discovery técnica — en 45 minutos definimos tu arquitectura, los módulos prioritarios y el roadmap de implementación.

JC
Autor

Julian Chaparro

Software Architect & Data Scientist · WeWebApp Solutions SAS

Arquitecto de software y científico de datos con 15+ años de experiencia diseñando sistemas cloud de alta disponibilidad en Azure, Python y .NET para empresas en Latinoamérica. Especializado en migraciones ERP, arquitecturas de microservicios y automatización de procesos con RPA e IA para PyMEs y empresas medianas. Ha liderado proyectos de transformación digital en sectores como FinTech, E-commerce, servicios ambientales y logística en Colombia, México y España.

Azure CloudPython DjangoFastAPISQL ServerRPAData ScienceMachine Learning