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)