almeira-web/scripts/notify_billing_whatsapp.py

74 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import urllib.request
import json
import ssl
import sys
import io
if sys.platform == 'win32':
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
EVOLUTION_API_URL = "https://evolution.almeira.com.co"
EVOLUTION_API_KEY = "EE49029EEB85-4568-8F81-C9FDFC6E2943"
INSTANCE_NAME = "AutomataAlmeira"
TARGET_PHONE = "573167455877"
APK_URL = "https://pacifictrans.almeira.com.co/PacifictransGo.apk"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
text_msg = (
"📑 *Pacific Trans GO: Consolidación Mensual de Comisiones & Facturación DIAN*\n\n"
"¡Hola Carlos! Se ha implementado con éxito la arquitectura completa de consolidación mensual y control fiscal en la plataforma:\n\n"
"1️⃣ *Esquema y Migración de Base de Datos:*\n"
"• Tabla: `cierres_facturacion_mensual` (UUID PK, Conductor ID, NIT/Cédula, Razón Social, Correo, Mes, Año, Comisiones Acumuladas, Total Viajes, Estado Facturación, Fecha Cierre).\n"
"• Migración SQL creada en `migrations/001_create_cierres_facturacion_mensual.sql` y Modelo Mongoose con persistencia autónoma.\n\n"
"2️⃣ *Cron Job de Corte Mensual Automático:*\n"
"• Programado para ejecutarse el día 1 de cada mes a las 00:00 horas (`0 0 1 * *`).\n"
"• ⚠️ *Cálculo Estricto:* Basado *ÚNICAMENTE* en la comisión de software cobrada/retenida a los conductores y *NUNCA* en el valor total de los viajes.\n"
"• Registro inicial en estado `'pendiente_proceso'`.\n\n"
"3️⃣ *Endpoint de Exportación a Excel / CSV (DIAN):*\n"
"• `GET /api/admin/billing/reporte-mensual?mes=X&anio=Y&format=csv`\n"
"• Columnas exactas para copiado/pegado masivo en el portal DIAN: `ID_Cierre, NIT/Cédula, Conductor, Correo, Total_Comisión, Cantidad_Viajes` con codificación UTF-8 BOM.\n\n"
"4️⃣ *Acciones en Masa y Control de Estados:*\n"
"• `POST /api/admin/billing/marcar-facturado` recibiendo arreglo de `IDs_Cierre`.\n"
"• Actualiza el estado a `'facturado_manual'` para evitar duplicidad de facturas en la DIAN.\n\n"
"5️⃣ *Panel Administrativo Web:*\n"
"• Sub-pestaña `📑 6. Cierres & Facturación DIAN` con selector de mes/año, KPIs fiscales, disparador manual de corte, selección múltiple y descarga directa del archivo CSV.\n\n"
f"📲 *APK Android Oficial:* {APK_URL}"
)
print("Enviando mensaje de texto a WhatsApp...", flush=True)
req_text = urllib.request.Request(
f"{EVOLUTION_API_URL}/message/sendText/{INSTANCE_NAME}",
data=json.dumps({"number": TARGET_PHONE, "text": text_msg, "delay": 300}).encode("utf-8"),
headers={"apikey": EVOLUTION_API_KEY, "Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req_text, context=ctx, timeout=60) as resp:
print(" [OK] Mensaje de texto enviado a WhatsApp (Status:", resp.status, ")", flush=True)
except Exception as e:
print(" [Error texto WhatsApp]:", e, flush=True)
print("Enviando APK como documento adjunto a WhatsApp...", flush=True)
req_media = urllib.request.Request(
f"{EVOLUTION_API_URL}/message/sendMedia/{INSTANCE_NAME}",
data=json.dumps({
"number": TARGET_PHONE,
"mediatype": "document",
"mimetype": "application/vnd.android.package-archive",
"fileName": "PacifictransGo.apk",
"caption": "📦 *PacifictransGo.apk* - Instalador Oficial Pacific Trans GO",
"media": APK_URL
}).encode("utf-8"),
headers={"apikey": EVOLUTION_API_KEY, "Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req_media, context=ctx, timeout=120) as resp:
print(" [OK] Documento APK enviado a WhatsApp (Status:", resp.status, ")", flush=True)
except Exception as e:
print(" [Error documento WhatsApp]:", e, flush=True)
print("Notificación WhatsApp finalizada.", flush=True)