fix: solved problem in msql query

master
adriano 2025-09-25 09:30:11 -03:00
parent 7e75d15a27
commit 4dcdcbb743
1 changed files with 75 additions and 62 deletions

View File

@ -18,8 +18,7 @@ import json
class TranscriptionReportService: class TranscriptionReportService:
def __init__(self, company_id: str, start_date: str, end_date: str): def __init__(self, company_id: str, start_date: str, end_date: str):
self.company_id = str(company_id) self.company_id = str(company_id)
self.start_date = start_date self.start_date = start_date
self.end_date = end_date
self.end_date = end_date self.end_date = end_date
self.mongo_client = current_app.mongo_client self.mongo_client = current_app.mongo_client
self.mongo_results = [] self.mongo_results = []
@ -178,83 +177,97 @@ class TranscriptionReportService:
} }
def _fetch_mysql_data(self, hit_report: Optional[bool] = False)-> List[Dict[str, Any]]: def _fetch_mysql_data(self, hit_report: Optional[bool] = False) -> List[Dict[str, Any]]:
# Carrega tabela de produtos (usada depois em client_price_row)
collection = self.mongo_client["billing-api"]["api_products"]
products = list(collection.find({}))
collection = self.mongo_client["billing-api"]["api_products"] # IDs vindos do Mongo (sessionId). Se vazio, nada a consultar.
ids = [str(uid) for uid in self.unique_ids]
if not ids:
return []
products = list(collection.find({})) # Monta IN(...) seguro contra quote simples e compatível com 1 ou N itens
def _sql_quote(v: str) -> str:
return "'" + v.replace("'", "''") + "'"
sql = f"""SELECT in_clause = "(" + ",".join(_sql_quote(v) for v in ids) + ")"
uniqueid,
src,
dst,
MIN(calldate) AS start_call,
MAX(calldate) AS end_call,
SUM(CASE
WHEN dstchannel LIKE 'PJSIP/%' AND lastapp = 'Queue'
THEN billsec
ELSE 0
END) AS total_billsec
FROM
tab_cdr
WHERE
uniqueid IN {tuple(self.unique_ids)}
GROUP BY
uniqueid, src, dst;"""
rows = execute_query(self.company_id, sql)
if hit_report: sql = f"""
for row in rows: SELECT
row["companyId"] = self.company_id uniqueid,
src,
dst,
MIN(calldate) AS start_call,
MAX(calldate) AS end_call,
SUM(
CASE
WHEN dstchannel LIKE 'PJSIP/%' AND lastapp = 'Queue' THEN billsec
ELSE 0
END
) AS total_billsec
FROM tab_cdr
WHERE uniqueid IN {in_clause}
GROUP BY uniqueid, src, dst;
"""
if rowMongo := next((m for m in self.mongo_results if m["_id"] == row["uniqueid"] ), None): rows = execute_query(self.company_id, sql)
row["custo_hit"] = f"{float(rowMongo["totalCost"])}"
token_output = rowMongo.get('usageByType', {}).get('output', {}) if hit_report:
token_input = rowMongo.get('usageByType', {}).get('input',{}) for row in rows:
row["companyId"] = self.company_id
row["qtd_token_input"] = token_input.get('usage', 0)
row["qtd_token_output"] = token_output.get('usage', 0) rowMongo = next((m for m in self.mongo_results if m["_id"] == row["uniqueid"]), None)
row["total_cost_token"] = float(token_input.get('usageCost',0) + token_output.get('usageCost', 0)) if rowMongo:
row["llm_provider"] = token_output.get('provider','unknown') row["custo_hit"] = str(float(rowMongo["totalCost"]))
stt = rowMongo.get('usageByType', {}).get('stt',{}) usage_by_type = rowMongo.get("usageByType", {})
token_output = usage_by_type.get("output", {})
if not stt: token_input = usage_by_type.get("input", {})
stt = rowMongo.get('usageByType', {}).get('input-audio',{})
row["qtd_token_input"] = token_input.get("usage", 0)
row["qtd_token_output"] = token_output.get("usage", 0)
row["total_cost_token"] = float(token_input.get("usageCost", 0) + token_output.get("usageCost", 0))
row["llm_provider"] = token_output.get("provider", "unknown")
stt = usage_by_type.get("stt", {})
if not stt:
stt = usage_by_type.get("input-audio", {})
token_by_second = 1920 / 60 # tokens por segundo usando modelo gemini 2.5 flash input audio
usageSeconds = round(stt.get("usage", 0) / token_by_second)
# seconds model_name = stt.get("product", "unknown")
token_by_second = 1920 / 60 # Cobrança de token por minuto do modelo gemini flash 2.5 input de audio
usageSeconds = round(stt.get('usage', 0) / token_by_second)
row["stt_model"] = stt.get('product', 'unknown')
row["stt_provider"] = stt.get('provider', 'unknown')
row["stt_cost"] = rowMongo["totalCost"]
row["stt_usage"] = usageSeconds
else: if "-input-audio" in model_name:
row["stt_model"] = stt.get('product', 'unknown') # Ajuste para situações como gemini-2.5-flash-input-audio para modificar para gemini-2.5-flash
row["stt_provider"] = stt.get('provider', 'unknown') model_name = model_name.replace("-input-audio", "")
row["stt_cost"] = stt.get('usageCost', 0)
row["stt_usage"] = stt.get('usage', 0) row["stt_model"] = model_name
row["stt_provider"] = stt.get("provider", "unknown")
row["stt_cost"] = rowMongo["totalCost"]
row["stt_usage"] = usageSeconds
else:
row["stt_model"] = stt.get("product", "unknown")
row["stt_provider"] = stt.get("provider", "unknown")
row["stt_cost"] = stt.get("usageCost", 0)
row["stt_usage"] = stt.get("usage", 0)
row["total_min"] = f"{(int(row['total_billsec']) / 60):.2f}" row["total_min"] = f"{(int(row['total_billsec']) / 60):.2f}"
self.client_price_row(products, row) self.client_price_row(products, row)
self.formate_properties(row) self.formate_properties(row)
else: else:
for row in rows: for row in rows:
row["total_min"] = f"{(int(row['total_billsec']) / 60):.2f}" row["total_min"] = f"{(int(row['total_billsec']) / 60):.2f}"
self.client_price_row(products, row) self.client_price_row(products, row)
self.formate_properties(row) self.formate_properties(row)
return rows return rows
def formate_properties(self, row): def formate_properties(self, row):
for key in row: for key in row:
if isinstance(row[key], datetime): if isinstance(row[key], datetime):