74 lines
3.9 KiB
Python
74 lines
3.9 KiB
Python
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)
|