Spaces:
Sleeping
Sleeping
Adzacam commited on
Commit ·
64bc767
1
Parent(s): 120ac93
feat: implement marketing data ingestion with normalization and add bulk deduplication/cleaning to financial records
Browse files- app.py +112 -2
- diccionario_normalizacion.json +224 -0
app.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
import os
|
|
|
|
| 2 |
import datetime
|
| 3 |
import logging
|
| 4 |
import re
|
|
@@ -8,6 +9,14 @@ from pydantic import BaseModel, ConfigDict, Field, field_validator
|
|
| 8 |
import rapidfuzz
|
| 9 |
import pandas as pd
|
| 10 |
from typing import List, Optional, Dict, Any
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
from sqlalchemy.orm import Session
|
| 12 |
from database import (
|
| 13 |
get_db,
|
|
@@ -784,8 +793,71 @@ def procesar_lote_encuestas(payloads: List[Dict[str, Any]], db: Session = Depend
|
|
| 784 |
|
| 785 |
@app.post("/api/v1/ingest/marketing", status_code=status.HTTP_201_CREATED)
|
| 786 |
def procesar_lote_marketing(payloads: List[Dict[str, Any]], db: Session = Depends(get_db)):
|
| 787 |
-
"""
|
| 788 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 789 |
|
| 790 |
@app.post("/api/v1/ingesta/financiera/bulk", status_code=status.HTTP_201_CREATED)
|
| 791 |
def procesar_lote_financiero(payloads: List[FinancePayload], db: Session = Depends(get_db), current_user: Users = Depends(get_current_user)):
|
|
@@ -1272,6 +1344,44 @@ def batch_analyze_nlp(
|
|
| 1272 |
else:
|
| 1273 |
records = payload.records
|
| 1274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1275 |
results = []
|
| 1276 |
estudiantes_existentes = db.query(DimEstudiante).all()
|
| 1277 |
|
|
|
|
| 1 |
import os
|
| 2 |
+
import json
|
| 3 |
import datetime
|
| 4 |
import logging
|
| 5 |
import re
|
|
|
|
| 9 |
import rapidfuzz
|
| 10 |
import pandas as pd
|
| 11 |
from typing import List, Optional, Dict, Any
|
| 12 |
+
|
| 13 |
+
# ── Carga del diccionario de normalización ────────────────────────────────────
|
| 14 |
+
_DICT_PATH = os.path.join(os.path.dirname(__file__), "diccionario_normalizacion.json")
|
| 15 |
+
try:
|
| 16 |
+
with open(_DICT_PATH, "r", encoding="utf-8") as _f:
|
| 17 |
+
DICCIONARIO_NORMALIZACION = json.load(_f)
|
| 18 |
+
except Exception:
|
| 19 |
+
DICCIONARIO_NORMALIZACION = {}
|
| 20 |
from sqlalchemy.orm import Session
|
| 21 |
from database import (
|
| 22 |
get_db,
|
|
|
|
| 793 |
|
| 794 |
@app.post("/api/v1/ingest/marketing", status_code=status.HTTP_201_CREATED)
|
| 795 |
def procesar_lote_marketing(payloads: List[Dict[str, Any]], db: Session = Depends(get_db)):
|
| 796 |
+
"""
|
| 797 |
+
Bulk Insert real de datos de Marketing/Ventas en fact_marketing.
|
| 798 |
+
Recibe una lista de dicts con raw_data del frontend y los inserta
|
| 799 |
+
resolviendo las dimensiones id_modulo e id_tiempo.
|
| 800 |
+
"""
|
| 801 |
+
try:
|
| 802 |
+
from sqlalchemy import func
|
| 803 |
+
|
| 804 |
+
existing_modulos = {m.nombre_modulo: m.id_modulo for m in db.query(DimModulo).all()}
|
| 805 |
+
existing_tiempos = {t.id_tiempo for t in db.query(DimTiempo).all()}
|
| 806 |
+
|
| 807 |
+
hechos_mkt = []
|
| 808 |
+
for p in payloads:
|
| 809 |
+
raw = p.get("raw_data", p) if isinstance(p, dict) else p
|
| 810 |
+
|
| 811 |
+
# Resolver módulo/programa
|
| 812 |
+
programa_raw = raw.get("programa") or raw.get("modulo") or raw.get("data_domain", "Marketing General")
|
| 813 |
+
# Aplicar normalización del diccionario
|
| 814 |
+
norm_progs = DICCIONARIO_NORMALIZACION.get("programas_cursos", {})
|
| 815 |
+
programa_clean = norm_progs.get(programa_raw, programa_raw)
|
| 816 |
+
|
| 817 |
+
id_modulo_val = existing_modulos.get(programa_clean)
|
| 818 |
+
if not id_modulo_val:
|
| 819 |
+
nuevo_modulo = DimModulo(
|
| 820 |
+
nombre_modulo=programa_clean,
|
| 821 |
+
nombre_institucion=raw.get("institucion", "GiraGroup"),
|
| 822 |
+
programa=programa_clean
|
| 823 |
+
)
|
| 824 |
+
db.add(nuevo_modulo)
|
| 825 |
+
db.flush()
|
| 826 |
+
id_modulo_val = nuevo_modulo.id_modulo
|
| 827 |
+
existing_modulos[programa_clean] = id_modulo_val
|
| 828 |
+
|
| 829 |
+
# Resolver tiempo
|
| 830 |
+
id_tiempo_val = raw.get("id_tiempo", 1)
|
| 831 |
+
if id_tiempo_val not in existing_tiempos:
|
| 832 |
+
db.add(DimTiempo(id_tiempo=id_tiempo_val, gestion=2026, semestre=1, mes="Junio"))
|
| 833 |
+
db.flush()
|
| 834 |
+
existing_tiempos.add(id_tiempo_val)
|
| 835 |
+
|
| 836 |
+
# Extraer métricas de marketing
|
| 837 |
+
leads_val = int(raw.get("leads", 1))
|
| 838 |
+
reservas_val = int(raw.get("reservas", 0))
|
| 839 |
+
inscritos_val = int(raw.get("inscritos", 0))
|
| 840 |
+
costo_val = float(raw.get("costo", raw.get("costo_programa", 0)))
|
| 841 |
+
|
| 842 |
+
hechos_mkt.append(FactMarketingInscripciones(
|
| 843 |
+
id_modulo=id_modulo_val,
|
| 844 |
+
id_tiempo=id_tiempo_val,
|
| 845 |
+
leads=leads_val,
|
| 846 |
+
reservas=reservas_val,
|
| 847 |
+
inscritos=inscritos_val,
|
| 848 |
+
costo_programa=costo_val
|
| 849 |
+
))
|
| 850 |
+
|
| 851 |
+
if hechos_mkt:
|
| 852 |
+
db.add_all(hechos_mkt)
|
| 853 |
+
db.commit()
|
| 854 |
+
|
| 855 |
+
return {"status": "success", "inserted": len(hechos_mkt)}
|
| 856 |
+
except Exception as e:
|
| 857 |
+
db.rollback()
|
| 858 |
+
import traceback
|
| 859 |
+
traceback.print_exc()
|
| 860 |
+
raise HTTPException(status_code=500, detail=str(e))
|
| 861 |
|
| 862 |
@app.post("/api/v1/ingesta/financiera/bulk", status_code=status.HTTP_201_CREATED)
|
| 863 |
def procesar_lote_financiero(payloads: List[FinancePayload], db: Session = Depends(get_db), current_user: Users = Depends(get_current_user)):
|
|
|
|
| 1344 |
else:
|
| 1345 |
records = payload.records
|
| 1346 |
|
| 1347 |
+
# ── Deduplicación con Pandas (todas las columnas) ─────────────────────
|
| 1348 |
+
try:
|
| 1349 |
+
records_dicts = [r.model_dump() if hasattr(r, 'model_dump') else r.dict() for r in records]
|
| 1350 |
+
df_records = pd.DataFrame(records_dicts)
|
| 1351 |
+
original_count = len(df_records)
|
| 1352 |
+
df_records = df_records.drop_duplicates()
|
| 1353 |
+
dedup_count = original_count - len(df_records)
|
| 1354 |
+
if dedup_count > 0:
|
| 1355 |
+
logger.info(f"drop_duplicates eliminó {dedup_count} registros duplicados exactos de {original_count}")
|
| 1356 |
+
# ── Normalización con diccionario ─────────────────────────────────
|
| 1357 |
+
norm_progs = DICCIONARIO_NORMALIZACION.get("programas_cursos", {})
|
| 1358 |
+
norm_ciudades = DICCIONARIO_NORMALIZACION.get("departamentos_ciudades", {})
|
| 1359 |
+
norm_grupos = DICCIONARIO_NORMALIZACION.get("grupos_sede", {})
|
| 1360 |
+
norm_estados = DICCIONARIO_NORMALIZACION.get("estados_financieros", {})
|
| 1361 |
+
norm_estados_arca = DICCIONARIO_NORMALIZACION.get("estados_academicos_arca", {})
|
| 1362 |
+
if "programa" in df_records.columns:
|
| 1363 |
+
# Eliminar versiones como "v.3", "2° Versión", "3ª Versión" antes del cruce
|
| 1364 |
+
df_records["programa"] = df_records["programa"].str.replace(r'(?i)\s*(v\.\d+|\d+[°ª]\s*Versi[oó]n).*$', '', regex=True)
|
| 1365 |
+
df_records["programa"] = df_records["programa"].replace(norm_progs)
|
| 1366 |
+
if "modulo" in df_records.columns:
|
| 1367 |
+
df_records["modulo"] = df_records["modulo"].replace(norm_progs)
|
| 1368 |
+
if "ciudad" in df_records.columns:
|
| 1369 |
+
df_records["ciudad"] = df_records["ciudad"].replace(norm_ciudades)
|
| 1370 |
+
df_records["ciudad"] = df_records["ciudad"].replace(norm_grupos)
|
| 1371 |
+
if "estado_cartera" in df_records.columns:
|
| 1372 |
+
df_records["estado_cartera"] = df_records["estado_cartera"].replace(norm_estados)
|
| 1373 |
+
for col_arca in ["estado_academico", "estado_tutoria", "estado_arca"]:
|
| 1374 |
+
if col_arca in df_records.columns:
|
| 1375 |
+
df_records[col_arca] = df_records[col_arca].replace(norm_estados_arca)
|
| 1376 |
+
# Reconstruir records desde DataFrame normalizado
|
| 1377 |
+
if hasattr(records[0], 'model_validate'):
|
| 1378 |
+
RecordClass = type(records[0])
|
| 1379 |
+
records = [RecordClass.model_validate(row) for row in df_records.to_dict(orient="records")]
|
| 1380 |
+
else:
|
| 1381 |
+
records = [type(records[0])(**row) for row in df_records.to_dict(orient="records")]
|
| 1382 |
+
except Exception as e:
|
| 1383 |
+
logger.warning(f"drop_duplicates/normalización falló (procesando sin dedup): {e}")
|
| 1384 |
+
|
| 1385 |
results = []
|
| 1386 |
estudiantes_existentes = db.query(DimEstudiante).all()
|
| 1387 |
|
diccionario_normalizacion.json
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"programas_cursos": {
|
| 3 |
+
"MBA": "Administración de Empresas (MBA)",
|
| 4 |
+
"Maestria MBA": "Administración de Empresas (MBA)",
|
| 5 |
+
"Maestría MBA": "Administración de Empresas (MBA)",
|
| 6 |
+
"Maestria Administracion": "Administración de Empresas (MBA)",
|
| 7 |
+
"Maestría Administración": "Administración de Empresas (MBA)",
|
| 8 |
+
"Maestria Transformacion Digital": "Transformación Digital e Innovación Empresarial Basada en Inteligencia Artificial",
|
| 9 |
+
"Maestría Transformación Digital": "Transformación Digital e Innovación Empresarial Basada en Inteligencia Artificial",
|
| 10 |
+
"Maestria IA": "Transformación Digital e Innovación Empresarial Basada en Inteligencia Artificial",
|
| 11 |
+
"Maestría IA": "Transformación Digital e Innovación Empresarial Basada en Inteligencia Artificial",
|
| 12 |
+
"Maestria Neurociencia": "Neurociencia Aplicada",
|
| 13 |
+
"Maestría Neurociencia": "Neurociencia Aplicada",
|
| 14 |
+
"Maestria Marketing": "Marketing Inteligente y Gestión Comercial",
|
| 15 |
+
"Maestría Marketing": "Marketing Inteligente y Gestión Comercial",
|
| 16 |
+
"Maestria Marketing Inteligente": "Marketing Inteligente y Gestión Comercial",
|
| 17 |
+
"Maestría Marketing Inteligente": "Marketing Inteligente y Gestión Comercial",
|
| 18 |
+
"Maestria Gestion Hospitalaria": "Gestión Hospitalaria y Gerencia de Salud",
|
| 19 |
+
"Maestría Gestión Hospitalaria": "Gestión Hospitalaria y Gerencia de Salud",
|
| 20 |
+
"Maestria Salud": "Gestión Hospitalaria y Gerencia de Salud",
|
| 21 |
+
"Maestría Salud": "Gestión Hospitalaria y Gerencia de Salud",
|
| 22 |
+
"Diplomado Educacion Superior": "Educación Superior por Competencias e Innovación Tecnológica",
|
| 23 |
+
"Diplomado Educación Superior": "Educación Superior por Competencias e Innovación Tecnológica",
|
| 24 |
+
"Diplomado TIC": "Educación Superior por Competencias e Innovación Tecnológica",
|
| 25 |
+
"Diplomado TICs": "Educación Superior por Competencias e Innovación Tecnológica",
|
| 26 |
+
"Diplomado IA Educacion": "Inteligencia Artificial Aplicada a la Educación",
|
| 27 |
+
"Diplomado IA Educación": "Inteligencia Artificial Aplicada a la Educación",
|
| 28 |
+
"Diplomado Marketing Digital": "Marketing Digital y Social Ads",
|
| 29 |
+
"Diplomado Mkt Digital": "Marketing Digital y Social Ads",
|
| 30 |
+
"Diplomado Social Ads": "Marketing Digital y Social Ads",
|
| 31 |
+
"Diplomado Marketing Farmaceutico": "Marketing Farmacéutico",
|
| 32 |
+
"Diplomado Marketing Farmacéutico": "Marketing Farmacéutico",
|
| 33 |
+
"Diplomado Mkt Farma": "Marketing Farmacéutico",
|
| 34 |
+
"Diplomado Gerencia Financiera": "Gerencia Financiera y Administración de Negocios",
|
| 35 |
+
"Diplomado Finanzas": "Gerencia Financiera y Administración de Negocios",
|
| 36 |
+
"Diplomado Medicina Estetica": "Medicina Estética",
|
| 37 |
+
"Diplomado Medicina Estética": "Medicina Estética",
|
| 38 |
+
"Diplomado Ozonoterapia": "Protocolos Fundamentales en Ozonoterapia",
|
| 39 |
+
"Diplomado Preparaciones Magistrales": "Preparaciones Magistrales y Buenas Prácticas de Elaboración",
|
| 40 |
+
"Diplomado Emergencias Medicas": "Emergencias Médicas: Traumas y Soporte Vital Avanzado",
|
| 41 |
+
"Diplomado Emergencias Médicas": "Emergencias Médicas: Traumas y Soporte Vital Avanzado",
|
| 42 |
+
"Diplomado Derecho Bancario": "Derecho Bancario y Bursátil (Enfoque Nacional e Internacional)",
|
| 43 |
+
"Diplomado Talento Humano": "Gestión y Administración de Talento Humano",
|
| 44 |
+
"Diplomado RRHH": "Gestión y Administración de Talento Humano",
|
| 45 |
+
"Diplomado RR.HH.": "Gestión y Administración de Talento Humano",
|
| 46 |
+
"Maestr. RRHH": "Gestión y Administración de Talento Humano",
|
| 47 |
+
"Maestría en RR.HH.": "Gestión y Administración de Talento Humano",
|
| 48 |
+
"Diplomado Psicologia Clinica": "Psicología Clínica y Psicoterapia Centrada en Procesos",
|
| 49 |
+
"Diplomado Psicología Clínica": "Psicología Clínica y Psicoterapia Centrada en Procesos",
|
| 50 |
+
"Experto Costos": "Gestión Estratégica de Costos",
|
| 51 |
+
"Experto Gestion Costos": "Gestión Estratégica de Costos",
|
| 52 |
+
"Experto Gestión Costos": "Gestión Estratégica de Costos",
|
| 53 |
+
"Experto Asesoria Financiera": "Asesoría y Gestión Financiera",
|
| 54 |
+
"Experto Asesoría Financiera": "Asesoría y Gestión Financiera",
|
| 55 |
+
"Experto Riesgo Financiero": "Gestión Integral de Riesgo Financiero",
|
| 56 |
+
"Experto IA TICs Educacion": "Inteligencia Artificial y TICs Aplicadas a la Educación",
|
| 57 |
+
"Experto IA TICs Educación": "Inteligencia Artificial y TICs Aplicadas a la Educación",
|
| 58 |
+
"Curso Edicion Video": "Edición de Video para Redes Sociales",
|
| 59 |
+
"Curso Edición Video": "Edición de Video para Redes Sociales",
|
| 60 |
+
"Curso Direccion Comercial": "Dirección Estratégica Comercial",
|
| 61 |
+
"Curso Dirección Comercial": "Dirección Estratégica Comercial",
|
| 62 |
+
"Curso Marketing Digital": "Marketing Digital (Curso corto)",
|
| 63 |
+
"Curso Salud Mental Infanto": "Salud Mental Infanto – Juvenil: Psicopatología de los Trastornos Mentales más Frecuentes",
|
| 64 |
+
"Curso Fotografia Odontologia": "Fotografía en Odontología y su Importancia Clínica",
|
| 65 |
+
"Curso Fotografía Odontología": "Fotografía en Odontología y su Importancia Clínica",
|
| 66 |
+
"Curso Flebologia": "Flebología y Linfología (Escleroterapia)",
|
| 67 |
+
"Curso Flebología": "Flebología y Linfología (Escleroterapia)",
|
| 68 |
+
"Curso Escritura Legal": "Curso en Escritura Legal y Jurisprudencia",
|
| 69 |
+
"Curso Obstetricia": "Curso en Obstetricia Clínica Integral",
|
| 70 |
+
"Curso Residencia Medica": "Curso Preparatorio para la Residencia Médica",
|
| 71 |
+
"Curso Residencia Médica": "Curso Preparatorio para la Residencia Médica",
|
| 72 |
+
"Curso Tablas Dinamicas": "Curso Tablas Dinámicas en Microsoft Excel",
|
| 73 |
+
"Curso Tablas Dinámicas": "Curso Tablas Dinámicas en Microsoft Excel",
|
| 74 |
+
"Curso Excel": "Curso Tablas Dinámicas en Microsoft Excel",
|
| 75 |
+
"Curso Contratacion Estado": "Curso Especializado en Procesos de Contratación del Estado",
|
| 76 |
+
"Curso Contratación Estado": "Curso Especializado en Procesos de Contratación del Estado",
|
| 77 |
+
"Curso Ethical Hacking": "Curso en Ethical Hacking-Pentesting",
|
| 78 |
+
"Curso Pentesting": "Curso en Ethical Hacking-Pentesting",
|
| 79 |
+
"Curso Psicologia Consumidor": "Curso en Psicología del Consumidor",
|
| 80 |
+
"Curso Psicología Consumidor": "Curso en Psicología del Consumidor",
|
| 81 |
+
"Curso Ciberseguridad": "Curso en Ciberseguridad y Educación Financiera",
|
| 82 |
+
"Curso Oficiales Credito": "Curso Formación de Oficiales de Crédito",
|
| 83 |
+
"Curso Oficiales Crédito": "Curso Formación de Oficiales de Crédito",
|
| 84 |
+
"Curso Herramientas Tecnologicas": "Curso en Uso de Herramientas Tecnológicas para Educadores",
|
| 85 |
+
"Curso Herramientas Tecnológicas": "Curso en Uso de Herramientas Tecnológicas para Educadores",
|
| 86 |
+
"Curso Bienestar Salud Mental": "Curso en Bienestar y Salud Mental en el Trabajo",
|
| 87 |
+
"Curso Redaccion Creativa": "Curso de Redacción Creativa para Redes Sociales",
|
| 88 |
+
"Curso Redacción Creativa": "Curso de Redacción Creativa para Redes Sociales",
|
| 89 |
+
"Curso Inteligencia Empresarial": "Curso Inteligencia Empresarial con Microsoft Excel",
|
| 90 |
+
"Curso Abdomen Agudo": "Curso en Manejo del Abdomen Agudo Quirúrgico",
|
| 91 |
+
"Curso Contenidos Educacion": "Curso en Creación de Contenidos en Educación en Redes Sociales",
|
| 92 |
+
"Curso Contenidos Educación": "Curso en Creación de Contenidos en Educación en Redes Sociales",
|
| 93 |
+
"Curso Atencion Cliente": "Curso en Atención al Cliente y Manejo de Conflictos",
|
| 94 |
+
"Curso Atención Cliente": "Curso en Atención al Cliente y Manejo de Conflictos"
|
| 95 |
+
},
|
| 96 |
+
"departamentos_ciudades": {
|
| 97 |
+
"Lp": "La Paz",
|
| 98 |
+
"LP": "La Paz",
|
| 99 |
+
"LPZ": "La Paz",
|
| 100 |
+
"Lpz": "La Paz",
|
| 101 |
+
"la paz": "La Paz",
|
| 102 |
+
"LA PAZ": "La Paz",
|
| 103 |
+
"Cbba": "Cochabamba",
|
| 104 |
+
"CBBA": "Cochabamba",
|
| 105 |
+
"cbba": "Cochabamba",
|
| 106 |
+
"cochabamba": "Cochabamba",
|
| 107 |
+
"COCHABAMBA": "Cochabamba",
|
| 108 |
+
"Scz": "Santa Cruz",
|
| 109 |
+
"SCZ": "Santa Cruz",
|
| 110 |
+
"scz": "Santa Cruz",
|
| 111 |
+
"Santa cruz": "Santa Cruz",
|
| 112 |
+
"santa cruz": "Santa Cruz",
|
| 113 |
+
"SANTA CRUZ": "Santa Cruz",
|
| 114 |
+
"Oruro": "Oruro",
|
| 115 |
+
"ORURO": "Oruro",
|
| 116 |
+
"Potosi": "Potosí",
|
| 117 |
+
"POTOSI": "Potosí",
|
| 118 |
+
"potosi": "Potosí",
|
| 119 |
+
"Sucre": "Sucre",
|
| 120 |
+
"SUCRE": "Sucre",
|
| 121 |
+
"Chuquisaca": "Sucre",
|
| 122 |
+
"CHUQUISACA": "Sucre",
|
| 123 |
+
"Tarija": "Tarija",
|
| 124 |
+
"TARIJA": "Tarija",
|
| 125 |
+
"Beni": "Trinidad",
|
| 126 |
+
"BENI": "Trinidad",
|
| 127 |
+
"Trinidad": "Trinidad",
|
| 128 |
+
"TRINIDAD": "Trinidad",
|
| 129 |
+
"Pando": "Cobija",
|
| 130 |
+
"PANDO": "Cobija",
|
| 131 |
+
"Cobija": "Cobija",
|
| 132 |
+
"COBIJA": "Cobija",
|
| 133 |
+
"El Alto": "El Alto",
|
| 134 |
+
"EL ALTO": "El Alto",
|
| 135 |
+
"el alto": "El Alto"
|
| 136 |
+
},
|
| 137 |
+
"universidades_instituciones": {
|
| 138 |
+
"GiraGroup": "GiraGroup Centro de Formación Continua",
|
| 139 |
+
"Gira Group": "GiraGroup Centro de Formación Continua",
|
| 140 |
+
"GIRAGROUP": "GiraGroup Centro de Formación Continua",
|
| 141 |
+
"giragroup": "GiraGroup Centro de Formación Continua",
|
| 142 |
+
"Gira": "GiraGroup Centro de Formación Continua",
|
| 143 |
+
"UMSA": "Universidad Mayor de San Andrés",
|
| 144 |
+
"UMSS": "Universidad Mayor de San Simón",
|
| 145 |
+
"UAGRM": "Universidad Autónoma Gabriel René Moreno",
|
| 146 |
+
"UCB": "Universidad Católica Boliviana San Pablo",
|
| 147 |
+
"UPB": "Universidad Privada Boliviana",
|
| 148 |
+
"UPEA": "Universidad Pública de El Alto",
|
| 149 |
+
"UTB": "Universidad Técnica de Bolivia",
|
| 150 |
+
"EMI": "Escuela Militar de Ingeniería",
|
| 151 |
+
"UNIVALLE": "Universidad Privada del Valle",
|
| 152 |
+
"UTO": "Universidad Técnica de Oruro",
|
| 153 |
+
"USFX": "Universidad Mayor, Real y Pontificia de San Francisco Xavier de Chuquisaca",
|
| 154 |
+
"UNIFRANZ": "Universidad Franz Tamayo",
|
| 155 |
+
"unifranz": "Universidad Franz Tamayo",
|
| 156 |
+
"Unifranz": "Universidad Franz Tamayo"
|
| 157 |
+
},
|
| 158 |
+
"estados_financieros": {
|
| 159 |
+
"AL DIA": "AL DÍA",
|
| 160 |
+
"al dia": "AL DÍA",
|
| 161 |
+
"Al Dia": "AL DÍA",
|
| 162 |
+
"Al dia": "AL DÍA",
|
| 163 |
+
"al día": "AL DÍA",
|
| 164 |
+
"ALDIA": "AL DÍA",
|
| 165 |
+
"EN MORA": "MORA",
|
| 166 |
+
"en mora": "MORA",
|
| 167 |
+
"En Mora": "MORA",
|
| 168 |
+
"mora": "MORA",
|
| 169 |
+
"PENDIENTE": "PENDIENTE",
|
| 170 |
+
"pendiente": "PENDIENTE",
|
| 171 |
+
"PAGADO": "PAGADO",
|
| 172 |
+
"pagado": "PAGADO",
|
| 173 |
+
"Pagado": "PAGADO",
|
| 174 |
+
"PROYECTADO": "PROYECTADO",
|
| 175 |
+
"proyectado": "PROYECTADO",
|
| 176 |
+
"PENDIENTE DE PAGO": "PENDIENTE",
|
| 177 |
+
"DERIVADO A LEGAL": "LEGAL",
|
| 178 |
+
"ACUERDO DE PAGO FIRMADO": "ACUERDO DE PAGO",
|
| 179 |
+
"EN GESTIÓN DE COBRO": "GESTIÓN DE COBRO",
|
| 180 |
+
"CARTERA CERRADA": "CARTERA CERRADA",
|
| 181 |
+
"CARTERA EN MORA": "CARTERA EN MORA",
|
| 182 |
+
"CARTERA VIGENTE": "CARTERA VIGENTE",
|
| 183 |
+
"CARTERA DADO DE BAJA": "CARTERA DADO DE BAJA"
|
| 184 |
+
},
|
| 185 |
+
"grupos_sede": {
|
| 186 |
+
"Grupo A - La Paz": "La Paz",
|
| 187 |
+
"Grupo B - La Paz": "La Paz",
|
| 188 |
+
"Grupo C - La Paz": "La Paz",
|
| 189 |
+
"Grupo A - Cochabamba": "Cochabamba",
|
| 190 |
+
"Grupo Cbba": "Cochabamba",
|
| 191 |
+
"Grupo CBBA": "Cochabamba",
|
| 192 |
+
"Grupo El Alto": "El Alto",
|
| 193 |
+
"Grupo C - El Alto": "El Alto",
|
| 194 |
+
"Grupo A - El Alto": "El Alto",
|
| 195 |
+
"Grupo B - El Alto": "El Alto",
|
| 196 |
+
"Grupo A - Santa Cruz": "Santa Cruz",
|
| 197 |
+
"Grupo B - Santa Cruz": "Santa Cruz",
|
| 198 |
+
"Grupo SCZ": "Santa Cruz",
|
| 199 |
+
"Grupo A - Oruro": "Oruro",
|
| 200 |
+
"Grupo B - Oruro": "Oruro",
|
| 201 |
+
"Grupo A - Sucre": "Sucre",
|
| 202 |
+
"Grupo B - Sucre": "Sucre",
|
| 203 |
+
"Grupo A - Tarija": "Tarija",
|
| 204 |
+
"Grupo B - Tarija": "Tarija",
|
| 205 |
+
"Grupo A - Trinidad": "Trinidad",
|
| 206 |
+
"Grupo A - Cobija": "Cobija",
|
| 207 |
+
"Grupo Virtual": "Virtual",
|
| 208 |
+
"Grupo Online": "Virtual",
|
| 209 |
+
"VIRTUAL": "Virtual",
|
| 210 |
+
"Online": "Virtual"
|
| 211 |
+
},
|
| 212 |
+
"estados_academicos_arca": {
|
| 213 |
+
"Aprobado": "APROBADO",
|
| 214 |
+
"Reprobado": "REPROBADO",
|
| 215 |
+
"Abandono": "ABANDONO",
|
| 216 |
+
"En Proceso": "EN PROCESO",
|
| 217 |
+
"Atrasado": "ATRASADO",
|
| 218 |
+
"Al Dia": "AL DÍA",
|
| 219 |
+
"Sin Tutoria": "SIN TUTORÍA",
|
| 220 |
+
"Emitido": "EMITIDO",
|
| 221 |
+
"Pendiente": "PENDIENTE",
|
| 222 |
+
"En Tramite": "EN TRÁMITE"
|
| 223 |
+
}
|
| 224 |
+
}
|