se agrega el modulo de powerbi.py para enviar el primer printscreen del dashboard de Power Bi

This commit is contained in:
GEORGE committed 2026-05-28 16:13:04 -05:00
1 parent 9ceeee0be1
commit e31f2676a3
7 files changed
+45 -110

No files matched your search

+3
View File
@@ -5,3 +5,6 @@ venv/
.DS_Store .DS_Store
.vscode/ .vscode/
.ide/ .ide/
test/
attachments/
logs/
+2 -9
View File
@@ -13,16 +13,9 @@
"attachments_folder": "attachments", "attachments_folder": "attachments",
"verify_ssl": false, "verify_ssl": false,
"ca_bundle": null, "ca_bundle": null,
"from_email": "business.intelligence@tagumedica.com", "from_email": "george.calle@tagumedica.com",
"to_email": [ "to_email": [
"jefes-area-comercial-tgm@tagumedica.com", "gcalle@pucp.pe", "business.intelligence@tagumedica.com"
"luis.wu@tagumedica.com",
"ricardo.palacios@tagumedica.com",
"eduard.samson@tagumedica.com",
"business.intelligence@tagumedica.com",
"hugo.condori@tagumedica.com",
"marco.marinos@tagumedica.com",
"natalie.arambulo@tagumedica.com"
] ]
}, },
"crystal": { "crystal": {
-31
View File
@@ -1,31 +0,0 @@
{
"hana": {
"server": "192.168.1.175",
"port": 30015,
"database": "SBO_TAGUMEDICA_21",
"user": "SYSTEM",
"password": "SAPB1Admin.25"
},
"outlook": {
"client_id": "957c324b-3da3-43ed-b912-ca52fb5d3128",
"client_secret": "Guc8Q~u6FH3xBKpxJ-hQ7QSpRWbnvmX.LnWr-dw7",
"tenant_id": "76f77b2f-6fc3-42a0-ae83-df05508405d6",
"attachments_folder": "attachments",
"verify_ssl": false,
"ca_bundle": null,
"from_email": "george.calle@tagumedica.com",
"to_email": [
"jefes-area-comercial-tgm@tagumedica.com",
"luis.wu@tagumedica.com",
"ricardo.palacios@tagumedica.com",
"eduard.samson@tagumedica.com",
"business.intelligence@tagumedica.com",
"hugo.condori@tagumedica.com",
"marco.marinos@tagumedica.com",
"natalie.arambulo@tagumedica.com"
]
},
"crystal": {
"path": "C:/Windows/Microsoft.NET/assembly/GAC_MSIL"
}
}
-36
View File
@@ -1,36 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Previsualización del Correo</title>
</head>
<body style="font-family: Arial, sans-serif; padding: 20px;">
<div style="max-width: 600px; margin: auto; border: 1px solid #ddd; padding: 20px; border-radius: 8px;">
<p style="color: gray; font-size: 0.8em; text-align: center; margin-top: 0;">--- PREVISUALIZACIÓN DEL CORREO ---
</p>
<hr style="border: 0; border-top: 1px solid #eee; margin-bottom: 20px;">
<h2 style="color: #2e6c80;">Informe Automático de Ventas</h2>
<p>Buenos días</p>
<p>Me complace compartir con ustedes el reporte de avance de ventas correspondiente al
<strong>13/05/2026</strong>.</p>
<p>La información se encuentra disponible en el siguiente dashboard:</p>
<p>
<a href="https://app.powerbi.com/view?r=eyJrIjoiNWQwY2E4Y2MtNmUyYy00Njc4LWI2YjUtOWQ3Zjc5ZjllNTM0IiwidCI6Ijc2Zjc3YjJmLTZmYzMtNDJhMC1hZTgzLWRmMDU1MDg0MDVkNiIsImMiOjR9"
target="_blank" style="color: #0056b3; text-decoration: none; font-weight: bold;">
Ver reporte Power BI
</a>
</p>
<div style="height: 20px;"></div>
<p>Quedamos atentos a cualquier consulta o comentario.</p>
<br>
<p style="font-weight: bold; margin-bottom: 0;">Saludos cordiales,</p>
<p style="font-weight: bold; margin-top: 5px;">Equipo de Inteligencia de Negocios</p>
<p style="font-size: 0.9em; color: #666; margin-top: 30px;">Este es un mensaje generado automáticamente por el
sistema de reportes.</p>
</div>
</body>
</html>
+10 -2
View File
@@ -4,6 +4,7 @@ import clr
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
from pathlib import Path from pathlib import Path
import logger_utilities import logger_utilities
import powerbi
# Importar configuración y utilidades personalizadas # Importar configuración y utilidades personalizadas
from outlook import get_access_token, send_email from outlook import get_access_token, send_email
@@ -144,13 +145,18 @@ def main():
# 4. Generación de Reportes # 4. Generación de Reportes
rpt_file = "venta_presupuesto_linea.rpt" rpt_file = "venta_presupuesto_linea.rpt"
adjuntos = [] adjuntos = []
# REPORTE DE POWER BI: Dashboard de Power BI
output_path = output_dir / f"dashboard_powerbi_{dt_previous_business_day.ToString('dd_MM_yyyy')}.png"
powerbi.get_default_page_title(output_path)
adjuntos.append(str(output_path))
# REPORTE 1: Venta del día de ayer # REPORTE 2: Venta del día de ayer
pdf_yesterday = output_dir / f"venta_presupuesto_linea_{dt_previous_business_day.ToString('dd_MM_yyyy')}.pdf" pdf_yesterday = output_dir / f"venta_presupuesto_linea_{dt_previous_business_day.ToString('dd_MM_yyyy')}.pdf"
if ejecutar_reporte(rpt_file, pdf_yesterday, {"FecIni": dt_previous_business_day, "FecFin": dt_previous_business_day}): if ejecutar_reporte(rpt_file, pdf_yesterday, {"FecIni": dt_previous_business_day, "FecFin": dt_previous_business_day}):
adjuntos.append(str(pdf_yesterday)) adjuntos.append(str(pdf_yesterday))
# REPORTE 2: Acumulado del mes actual (MTD) # REPORTE 3: Acumulado del mes actual (MTD)
pdf_mtd = output_dir / f"venta_presupuesto_linea_{dt_month_start.ToString('dd_MM_yyyy')}_al_{dt_previous_business_day.ToString('dd_MM_yyyy')}.pdf" pdf_mtd = output_dir / f"venta_presupuesto_linea_{dt_month_start.ToString('dd_MM_yyyy')}_al_{dt_previous_business_day.ToString('dd_MM_yyyy')}.pdf"
if ejecutar_reporte(rpt_file, pdf_mtd, {"FecIni": dt_month_start, "FecFin": dt_previous_business_day}): if ejecutar_reporte(rpt_file, pdf_mtd, {"FecIni": dt_month_start, "FecFin": dt_previous_business_day}):
adjuntos.append(str(pdf_mtd)) adjuntos.append(str(pdf_mtd))
@@ -215,3 +221,5 @@ if __name__ == "__main__":
print("="*60) print("="*60)
except Exception as e: except Exception as e:
print(f"FATAL MAIN ERROR: {e}") print(f"FATAL MAIN ERROR: {e}")
########################################################
+30
View File
@@ -0,0 +1,30 @@
from playwright.sync_api import sync_playwright
import time
from config_loader import CONFIG
########################################################
def get_default_page_title(output_path):
url = CONFIG.powerbi.url
with sync_playwright() as p:
# browser = p.chromium.launch(headless=True)
browser = p.chromium.launch(
headless=True,
executable_path=r"C:\Program Files\Google\Chrome\Application\chrome.exe"
)
page = browser.new_page(viewport={"width": 1920, "height": 1080})
page.goto(url, wait_until="networkidle")
# Espera extra porque Power BI suele seguir renderizando
time.sleep(10)
# Imprimir el título de la página por defecto
print(f"Título de la página por defecto: {page.title()}")
# Capturar la pantalla y guardarla en el archivo de salida especificado
page.screenshot(path=output_path
, full_page=True)
browser.close()
########################################################
-32
View File
@@ -1,32 +0,0 @@
import clr
import sys
from pathlib import Path
# Try to find the DLL
gac_path = r"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\CrystalDecisions.CrystalReports.Engine\v4.0_13.0.4000.0__692fbea5521e1304\CrystalDecisions.CrystalReports.Engine.dll"
print(f"Checking path: {gac_path}")
print(f"Exists: {Path(gac_path).exists()}")
try:
print("Attempting to add reference...")
# Try adding by full path first
clr.AddReference(gac_path)
print("Reference added successfully by path.")
except Exception as e:
print(f"Failed to add reference by path: {e}")
try:
print("Attempting to add reference by name...")
clr.AddReference("CrystalDecisions.CrystalReports.Engine")
print("Reference added successfully by name.")
except Exception as e2:
print(f"Failed to add reference by name: {e2}")
try:
print("Attempting import...")
# pyrefly: ignore [missing-import]
from CrystalDecisions.CrystalReports.Engine import ReportDocument
print("Import successful!")
except Exception as e:
print(f"Import failed: {e}")
import traceback
traceback.print_exc()