Actualizar backend/core/data_manager.py
This commit is contained in:
@@ -43,6 +43,7 @@ class DataManager:
|
|||||||
self.github_cronograma_url = f"{base}/SQL_QUERY_2/BASE_CRONOGRAMA_2.query"
|
self.github_cronograma_url = f"{base}/SQL_QUERY_2/BASE_CRONOGRAMA_2.query"
|
||||||
self.github_facturas_url = f"{base}/SQL_QUERY_2/BASE_FACTURAS_2.query"
|
self.github_facturas_url = f"{base}/SQL_QUERY_2/BASE_FACTURAS_2.query"
|
||||||
self.github_matriculas_url = f"{base}/SQL_QUERY_2/BASE_MATRICULADOS_2.query"
|
self.github_matriculas_url = f"{base}/SQL_QUERY_2/BASE_MATRICULADOS_2.query"
|
||||||
|
self.github_notascredito_url = f"{base}/SQL_QUERY_2/BASE_NOTASCREDITO_2.query"
|
||||||
|
|
||||||
# --- Variables de estado ---
|
# --- Variables de estado ---
|
||||||
self.config_data = {}
|
self.config_data = {}
|
||||||
@@ -57,6 +58,7 @@ class DataManager:
|
|||||||
self.query_matriculas_sql = ""
|
self.query_matriculas_sql = ""
|
||||||
self.query_cronograma_sql = ""
|
self.query_cronograma_sql = ""
|
||||||
self.query_facturas_sql = ""
|
self.query_facturas_sql = ""
|
||||||
|
self.query_notascredito_sql = ""
|
||||||
|
|
||||||
# Caché en memoria de las consultas ANUALES de cobranza. Evita re-ejecutar
|
# Caché en memoria de las consultas ANUALES de cobranza. Evita re-ejecutar
|
||||||
# la consulta del año COMPLETO en cada combinación de filtros (mes/sectorista/
|
# la consulta del año COMPLETO en cada combinación de filtros (mes/sectorista/
|
||||||
@@ -64,6 +66,7 @@ class DataManager:
|
|||||||
# consulta tiene éxito y se limpia en cada refresco (manual o ciclo 15 min).
|
# consulta tiene éxito y se limpia en cada refresco (manual o ciclo 15 min).
|
||||||
self._cache_cronograma = {} # str(ano) -> filas
|
self._cache_cronograma = {} # str(ano) -> filas
|
||||||
self._cache_facturas = {} # str(ano) -> filas
|
self._cache_facturas = {} # str(ano) -> filas
|
||||||
|
self._cache_notascredito = {} # str -> filas (rango completo)
|
||||||
|
|
||||||
self.cargar_toda_configuracion()
|
self.cargar_toda_configuracion()
|
||||||
|
|
||||||
@@ -87,6 +90,7 @@ class DataManager:
|
|||||||
"query_matriculas_sql": self.github_matriculas_url,
|
"query_matriculas_sql": self.github_matriculas_url,
|
||||||
"query_cronograma_sql": self.github_cronograma_url,
|
"query_cronograma_sql": self.github_cronograma_url,
|
||||||
"query_facturas_sql": self.github_facturas_url,
|
"query_facturas_sql": self.github_facturas_url,
|
||||||
|
"query_notascredito_sql": self.github_notascredito_url,
|
||||||
}
|
}
|
||||||
with ThreadPoolExecutor(max_workers=15) as ex:
|
with ThreadPoolExecutor(max_workers=15) as ex:
|
||||||
json_futs = {k: ex.submit(self._get_json, url, default) for k,(url,default) in json_tasks.items()}
|
json_futs = {k: ex.submit(self._get_json, url, default) for k,(url,default) in json_tasks.items()}
|
||||||
@@ -129,7 +133,7 @@ class DataManager:
|
|||||||
def get_connection(self):
|
def get_connection(self):
|
||||||
import pyodbc
|
import pyodbc
|
||||||
conn_str = (
|
conn_str = (
|
||||||
f"DRIVER={{ODBC Driver 17 for SQL Server}};"
|
f"DRIVER={{SQL Server}};"
|
||||||
f"SERVER={self.server};"
|
f"SERVER={self.server};"
|
||||||
f"DATABASE={self.database};"
|
f"DATABASE={self.database};"
|
||||||
f"UID={self.username};"
|
f"UID={self.username};"
|
||||||
@@ -699,13 +703,37 @@ class DataManager:
|
|||||||
print(f"❌ Error facturas cobranza: {e}")
|
print(f"❌ Error facturas cobranza: {e}")
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def ejecutar_consulta_notascredito(self):
|
||||||
|
"""Notas de crédito (rango completo, cacheado). El query no tiene año."""
|
||||||
|
en_cache = self._cache_notascredito.get("all")
|
||||||
|
if en_cache is not None:
|
||||||
|
return en_cache
|
||||||
|
try:
|
||||||
|
if not self.query_notascredito_sql:
|
||||||
|
return []
|
||||||
|
conn = self.get_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute(self.query_notascredito_sql)
|
||||||
|
columns = [col[0] for col in cursor.description]
|
||||||
|
results = [dict(zip(columns, row)) for row in cursor.fetchall()]
|
||||||
|
conn.close()
|
||||||
|
self._cache_notascredito["all"] = results
|
||||||
|
return results
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error notas de crédito: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
def traer_vendedor_cod_detalle(self, matriculas, ano=None, mes=None):
|
def traer_vendedor_cod_detalle(self, matriculas, ano=None, mes=None):
|
||||||
"""Dada una lista de num_matricula (POR RETIRAR, pocas), devuelve por cada una:
|
"""Dada una lista de num_matricula (POR RETIRAR, pocas), devuelve por cada una:
|
||||||
{num_matricula, dsc_vendedor, cod_detalle}. Consulta directa y ligera
|
{num_matricula, dsc_vendedor, cod_detalle, ...}. Consulta ligera.
|
||||||
(filtra solo esas matrículas). NO toca cobranza ni sus cachés."""
|
Las cuotas vencidas se cuentan HASTA EL FIN DEL MES (ano, mes) del filtro,
|
||||||
|
NO hasta la fecha de hoy (así septiembre no cambia al llegar octubre).
|
||||||
|
Si no se pasa ano/mes, usa la fecha de hoy (comportamiento anterior)."""
|
||||||
mats = [str(m).strip() for m in (matriculas or []) if str(m).strip()]
|
mats = [str(m).strip() for m in (matriculas or []) if str(m).strip()]
|
||||||
if not mats:
|
if not mats:
|
||||||
return {}
|
return {}
|
||||||
|
# Fecha de corte: primer día del mes SIGUIENTE al filtro (vencidas < corte).
|
||||||
|
# ini_mes = primer día del mes del filtro (para separar Anterior vs Curso).
|
||||||
corte_venc = "CAST(GETDATE() AS DATE)"
|
corte_venc = "CAST(GETDATE() AS DATE)"
|
||||||
ini_mes = "CAST(GETDATE() AS DATE)"
|
ini_mes = "CAST(GETDATE() AS DATE)"
|
||||||
if ano and mes:
|
if ano and mes:
|
||||||
@@ -777,20 +805,20 @@ class DataManager:
|
|||||||
WHERE c.cod_localidad = m.cod_localidad
|
WHERE c.cod_localidad = m.cod_localidad
|
||||||
AND c.num_matricula = m.num_matricula
|
AND c.num_matricula = m.num_matricula
|
||||||
AND c.num_refinanciamiento = m.num_refinanciamiento) AS imp_total_pagado,
|
AND c.num_refinanciamiento = m.num_refinanciamiento) AS imp_total_pagado,
|
||||||
ISNULL((SELECT SUM(c.imp_total - ISNULL(c.imp_dscto, 0))
|
ISNULL((SELECT SUM(c.imp_total - ISNULL(c.imp_dscto, 0))
|
||||||
FROM sgede_cronograma_matricula c
|
FROM sgede_cronograma_matricula c
|
||||||
WHERE c.cod_localidad = m.cod_localidad
|
WHERE c.cod_localidad = m.cod_localidad
|
||||||
AND c.num_matricula = m.num_matricula
|
AND c.num_matricula = m.num_matricula
|
||||||
AND c.num_refinanciamiento = 1), 0) AS inv_neta,
|
AND c.num_refinanciamiento = 1), 0) AS inv_neta,
|
||||||
m.cod_moneda AS cod_moneda,
|
m.cod_moneda AS cod_moneda,
|
||||||
ISNULL((SELECT TOP 1 comp.imp_tc
|
ISNULL((SELECT TOP 1 comp.imp_tc
|
||||||
FROM vtaca_comprobante comp
|
FROM vtaca_comprobante comp
|
||||||
INNER JOIN sgevi_cuotas_x_comprobante cxc
|
INNER JOIN sgevi_cuotas_x_comprobante cxc
|
||||||
ON comp.cod_localidad = cxc.cod_localidad
|
ON comp.cod_localidad = cxc.cod_localidad
|
||||||
AND comp.num_correlativo = cxc.num_correlativo
|
AND comp.num_correlativo = cxc.num_correlativo
|
||||||
WHERE cxc.cod_localidad_c = m.cod_localidad
|
WHERE cxc.cod_localidad_c = m.cod_localidad
|
||||||
AND cxc.num_matricula = m.num_matricula
|
AND cxc.num_matricula = m.num_matricula
|
||||||
ORDER BY comp.fch_emision DESC), 1) AS imp_tc
|
ORDER BY comp.fch_emision DESC), 1) AS imp_tc
|
||||||
FROM sgeca_matricula m
|
FROM sgeca_matricula m
|
||||||
INNER JOIN sgema_alumno a ON m.cod_alumno = a.cod_alumno
|
INNER JOIN sgema_alumno a ON m.cod_alumno = a.cod_alumno
|
||||||
WHERE m.num_matricula IN ({placeholders})
|
WHERE m.num_matricula IN ({placeholders})
|
||||||
@@ -801,13 +829,15 @@ class DataManager:
|
|||||||
conn.close()
|
conn.close()
|
||||||
out = {}
|
out = {}
|
||||||
for f in filas:
|
for f in filas:
|
||||||
|
# Si la matrícula está en DÓLARES, convertir montos a soles (× imp_tc).
|
||||||
_moneda = str(f.get("cod_moneda") or "SOL").strip().upper()
|
_moneda = str(f.get("cod_moneda") or "SOL").strip().upper()
|
||||||
try: _tc = float(f.get("imp_tc") or 1.0)
|
try: _tc = float(f.get("imp_tc") or 1.0)
|
||||||
except: _tc = 1.0
|
except: _tc = 1.0
|
||||||
if _moneda != "DOL" or _tc <= 0: _tc = 1.0
|
if _moneda != "DOL" or _tc <= 0:
|
||||||
|
_tc = 1.0
|
||||||
_mult = _tc if _moneda == "DOL" else 1.0
|
_mult = _tc if _moneda == "DOL" else 1.0
|
||||||
_pag = float(f.get("imp_total_pagado") or 0) * _mult
|
|
||||||
_inv = float(f.get("inv_neta") or 0) * _mult
|
_inv = float(f.get("inv_neta") or 0) * _mult
|
||||||
|
_pag = float(f.get("imp_total_pagado") or 0) * _mult
|
||||||
_mva = float(f.get("monto_venc_ant") or 0) * _mult
|
_mva = float(f.get("monto_venc_ant") or 0) * _mult
|
||||||
_mvc = float(f.get("monto_venc_cur") or 0) * _mult
|
_mvc = float(f.get("monto_venc_cur") or 0) * _mult
|
||||||
out[str(f.get("num_matricula", "")).strip()] = {
|
out[str(f.get("num_matricula", "")).strip()] = {
|
||||||
@@ -833,6 +863,7 @@ class DataManager:
|
|||||||
if ano is None:
|
if ano is None:
|
||||||
self._cache_cronograma.clear()
|
self._cache_cronograma.clear()
|
||||||
self._cache_facturas.clear()
|
self._cache_facturas.clear()
|
||||||
|
self._cache_notascredito.clear()
|
||||||
else:
|
else:
|
||||||
self._cache_cronograma.pop(str(ano), None)
|
self._cache_cronograma.pop(str(ano), None)
|
||||||
self._cache_facturas.pop(str(ano), None)
|
self._cache_facturas.pop(str(ano), None)
|
||||||
|
|||||||
Reference in New Issue
Block a user