Enviador de Órdenes - Core engine para reportes y generación de PDFs para PYMEs
Project description
📦 Enviador de Órdenes — README Oficial (Actualizado)
Sistema ligero, modular y escalable para cargar información desde Excel o entrada manual, generar PDF profesionales, y enviarlos automáticamente por Telegram y Email. Desarrollado en Python + Streamlit con un enfoque de DataOps para PYMEs.
🚀 1. Requisitos previos
✔ Python 3.13+
Obligatorio (ReportLab + Streamlit funcionan perfecto en 3.13).
✔ uv — Gestor moderno recomendado
Instalar:
curl -LsSf https://astral.sh/uv/install.sh | sh
Verificar:
uv --version
🧩 2. Clonar el repositorio
git clone https://github.com/tu-org/enviador_de_ordenes.git
cd enviador_de_ordenes
📁 3. Estructura real del proyecto
.
├── .env
├── .env.example
├── LICENSE
├── pyproject.toml
├── README.md
├── uv.lock
│
└── src/enviador_de_ordenes/
├── app.py # UI principal Streamlit
│
├── core/
│ ├── config.py # Carga y validación de .env
│ ├── domain.py # OrderForm, OrderItem (Pydantic)
│ ├── email_sender.py # SMTP email
│ ├── input_factory.py # Strategy pattern para inputs
│ ├── logger.py # Logging
│ ├── parsers.py # parse_excel_to_order_form()
│ ├── pdf_generator.py # generate_pdf() + show_pdf()
│ ├── telegram_sender.py # Envío Telegram
│ └── utils/
│ ├── dataframe_utils.py# Limpieza df
│ └── pdf_utils.py # Transformar items → DataFrame
│
├── strategies/
│ ├── excel_input.py # Carga desde Excel
│ └── manual_input.py # Carga manual
│
├── data/
│ ├── history.db # Base de datos SQLite (historial)
│ ├── inbox/ # Archivos entrantes
│ ├── logo.png # Opcional
│ └── logo.webp # Opcional
│
├── services/
│ ├── report_service.py # Servicios (no usado aún)
│ └── scheduler.py # Automatización (placeholder)
│
└── templates/
├── pdf/
│ └── base_template.py # Template profesional (Platypus)
└── ui/
└── styles.py # Estilos UI Streamlit
🎛 4. Instalación del entorno
Instalar dependencias:
uv sync
Esto:
- crea
.venv/ - instala todas las dependencias
- genera
uv.lock
🔧 5. Activar (opcional)
source .venv/bin/activate
🔐 6. Configuración del archivo .env
Copiar base:
cp .env.example .env
Editar:
📑 6.1. Integración con Google Sheets (Cuenta de servicio)
Si quieres guardar los pedidos en Google Sheets:
-
Crear la cuenta de servicio
- En Google Cloud Console, crea o selecciona un proyecto.
- Habilita la API de Google Sheets en ese proyecto.
- Ve a IAM y administración → Cuentas de servicio → Crear.
- Rol sugerido: Editor (o equivalente con acceso a Sheets).
- Genera clave JSON y descárgala.
-
Compartir el Sheet
- Crea tu spreadsheet en Google Sheets.
- Copia el ID del sheet (lo que va después de
/d/en la URL). - Comparte el sheet con el email de la cuenta de servicio con permiso de Editor.
-
Agregar credenciales al
.env(elige una opción):- Opción archivo:
GDRIVE_SERVICE_ACCOUNT_FILE=/ruta/credenciales.json - Opción base64 (pegar el JSON codificado):
Para codificar el JSON en macOS/Linux:GDRIVE_SERVICE_ACCOUNT_BASE64=<json_codificado_en_base64>base64 -w0 credenciales.json(obase64 credenciales.json | tr -d '\n'). - Además:
GOOGLE_SHEETS_ID=<id_del_spreadsheet> GOOGLE_SHEETS_WORKSHEET=Hoja1 # opcional
- Opción archivo:
Listo: al procesar un pedido, la app intentará agregar las filas al sheet.
📲 6.1. Configurar el BOT de Telegram desde cero
1️⃣ Crear el bot en BotFather
-
Abre Telegram (móvil o escritorio).
-
Busca el usuario @BotFather.
-
Escribe
/startsi es la primera vez. -
Envía el comando:
/newbot
-
BotFather te pedirá:
- Nombre del bot (ej:
Enviador de Órdenes) - Username del bot (debe terminar en
bot, por ejemplo:enviador_ordenes_bot).
- Nombre del bot (ej:
-
Al final te devolverá algo así:
Use this token to access the HTTP API: 1234567890:ABCDefGhIJKlmNoPQRstuVWxyZ
-
Ese valor es tu
TELEGRAM_BOT_TOKEN→ guárdalo en.env:TELEGRAM_BOT_TOKEN="1234567890:ABCDefGhIJKlmNoPQRstuVWxyZ"
2️⃣ Activar el bot (importante)
- Desde tu cuenta de Telegram, busca el bot por el username que creaste (ej:
@enviador_ordenes_bot). - Ábrelo y presiona Start o envíale cualquier mensaje (ej:
Hola). - Sin ese primer mensaje, el bot no puede escribirte.
3️⃣ Obtener el CHAT ID (conversación 1 a 1)
Opción A — vía API oficial:
-
Después de escribirle al bot, abre en el navegador:
https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getUpdates
-
Busca algo como:
"message": { "chat": { "id": 987654321, "first_name": "...", ... } }
-
Ese
987654321es tuTELEGRAM_CHAT_ID. Configúralo en.env:TELEGRAM_CHAT_ID="987654321"
Opción B — con bots tipo @userinfobot (por si algún día te toca):
- Habla con @userinfobot.
- Te responde tu
id. - Usas ese número como
TELEGRAM_CHAT_ID.
4️⃣ CHAT ID para grupos (por si lo usas más adelante)
-
Crea un grupo e incluye a tu bot.
-
En el grupo, escribe un mensaje y luego consulta:
https://api.telegram.org/bot<TELEGRAM_BOT_TOKEN>/getUpdates
-
Verás un
chat.idnegativo, algo tipo:"id": -1234567890123
-
Usa ese valor (con el signo menos) como
TELEGRAM_CHAT_ID.
5️⃣ Resumen de variables que deben quedar en .env
TELEGRAM_BOT_TOKEN="1234567890:ABCDefGhIJKlmNoPQRstuVWxyZ"
TELEGRAM_CHAT_ID="987654321" # o ID negativo si es grupo
📧 6.2. Obtener la contraseña de aplicación de Gmail (SMTP)
Esto es lo que siempre se olvida, así que lo dejamos paso a paso.
1️⃣ Activar la verificación en dos pasos (si no está activada)
- Entra a tu cuenta de Google: https://myaccount.google.com
- Ve a Seguridad (Security).
- En “Acceso a Google”, entra a Verificación en dos pasos.
- Actívala (Google te va a guiar con SMS, app de autenticación, etc.).
Sin 2FA, no aparece la opción de “Contraseñas de aplicación”.
2️⃣ Crear una contraseña de aplicación
-
En la misma sección de seguridad, entra a: Seguridad → Acceso a Google → Contraseñas de aplicaciones (en inglés: App passwords).
-
Si te la pide, vuelve a iniciar sesión.
-
En el selector:
- Aplicación: selecciona “Correo” (Mail) o “Otro (nombre personalizado)” y escribe algo como
Enviador de Órdenes. - Dispositivo: puedes dejar “Otro” o “Este dispositivo”.
- Aplicación: selecciona “Correo” (Mail) o “Otro (nombre personalizado)” y escribe algo como
-
Haz clic en Generar.
-
Google te mostrará una contraseña de 16 caracteres, algo tipo:
abcd efgh ijkl mnop
-
Copia esa contraseña (sin espacios) y guárdala como
SMTP_PASSWORDen.env.
3️⃣ Configurar las variables SMTP en .env
SMTP_SERVER="smtp.gmail.com"
SMTP_PORT=587
SMTP_USER="tu-correo@gmail.com"
SMTP_PASSWORD="abcd efgh ijkl mnop" # la contraseña de aplicación (puedes quitar espacios)
EMAIL_TO="destino1@empresa.com"
Puedes dejar la password con o sin espacios; lo más limpio:
SMTP_PASSWORD="abcdefghijklnmop"
4️⃣ Notas importantes (para que no te estalle en producción)
-
La contraseña de aplicación NO es tu contraseña normal de Gmail.
-
Si cambias algo crítico en tu cuenta (2FA, recuperación, etc.), Google a veces invalida contraseñas de aplicación → si un día deja de enviar, revisa ahí primero.
-
En entornos corporativos (Google Workspace), es posible que:
- El admin bloquee contraseñas de aplicación.
- Tengas que usar SMTP corporativo distinto (no
smtp.gmail.com).
🖥️ 7. Ejecutar la UI
uv run streamlit run src/enviador_de_ordenes/app.py
Funciones principales:
- Cargar Excel
- Ingreso manual con edición dinámica
- Validación automática de OrderForm
- PDF profesional (vertical, 2 columnas, multipágina)
- Vista previa del PDF embebida
- Enviar por Telegram
- Enviar por Email
- Historial en SQLite (opcional)
🧾 8. Generación de PDF profesional
El sistema usa:
✔ ReportLab + Platypus
✔ Template corporativo (base_template.py)
✔ Dos columnas por página (Frames)
✔ Repetición del encabezado en multipágina
✔ Resumen dinámico (OrderForm → PDF)
✔ Sin textos quemados (labels vienen del modelo)
✔ Logo corporativo opcional
PDF generado en:
src/enviador_de_ordenes/data/outbox/
🔄 9. Flujo interno del sistema
Excel / Manual input
↓
InputFactory (Strategy)
↓
parse_excel_to_order_form()
↓
OrderForm (Pydantic + metadata)
↓
generate_pdf(order)
↓
show_pdf()
↓
send_pdf_via_telegram()
send_pdf_email()
↓
history.db (pronto)
🧪 10. Ejecutar módulos manualmente
uv run python src/enviador_de_ordenes/core/pdf_generator.py
📦 11. Empaquetar para PYMEs (.exe)
uv add pyinstaller
uv run pyinstaller --onefile src/enviador_de_ordenes/app.py
Salida:
dist/app.exe
🛠 12. Personalización
Editar:
src/enviador_de_ordenes/templates/pdf/base_template.py
Puedes cambiar:
- Logo
- Colores
- Márgenes
- Tipografías
- Numero de columnas
- Footer
- Distribución del resumen
UI
Editar:
src/enviador_de_ordenes/templates/ui/styles.py
📌 13. Qué copia un cliente para ejecutar
- Python 3.13
- uv
.envcon Telegram/Email- Toda la carpeta del proyecto
- Crear carpeta
data/outbox(si no existe)
Con eso, corre sin dependencias adicionales.
🎉 14. Créditos
Desarrollado por Santiago Aguirre — Memento Software Factory
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file enviador_de_ordenes-0.3.2.tar.gz.
File metadata
- Download URL: enviador_de_ordenes-0.3.2.tar.gz
- Upload date:
- Size: 21.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c5b85cf0b10508a75a334f38aa4bb939dea9c1c9f7344a234ff70156abd1f24
|
|
| MD5 |
08c2b7c648dac5594abae33d3a859908
|
|
| BLAKE2b-256 |
5ba440ca5a3e56f4b79cb7694ea8ab2fdd38c93d09432d7115c1fcb896de9c40
|
File details
Details for the file enviador_de_ordenes-0.3.2-py3-none-any.whl.
File metadata
- Download URL: enviador_de_ordenes-0.3.2-py3-none-any.whl
- Upload date:
- Size: 28.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1305c176a88048a6e649dba017fd6ae4b0e1c85e256bbef688db446edc808d19
|
|
| MD5 |
3fd6e6b563dce6aa94ff995ec8cd92dd
|
|
| BLAKE2b-256 |
b0226a2e3378e49e206ad5e9e0cf52f976c95f125f832c5018691da260088bb9
|