Adzacam commited on
Commit
d07ea19
·
1 Parent(s): 432899b

feat: add dynamic DimTiempo resolution and support for projected collections in financial processing

Browse files
Files changed (1) hide show
  1. app.py +49 -13
app.py CHANGED
@@ -149,9 +149,13 @@ class ProcessSheetPayload(BaseModel):
149
  inscritos: Optional[int] = 0
150
  costo: Optional[float] = 0.0
151
 
152
- # Survey fields
153
  pregunta: Optional[str] = None
154
  puntuacion: Optional[float] = 0.0
 
 
 
 
 
155
 
156
  @field_validator('texto_celda')
157
  @classmethod
@@ -525,7 +529,7 @@ def procesar_lote_tabular(payloads: List[ProcessSheetPayload], db: Session = Dep
525
  # For default/generic fallback
526
  docentes_db = set(existing_docentes.values())
527
  modulos_db = {m.id_modulo for m in db.query(DimModulo).all()}
528
- tiempos_db = {t.id_tiempo for t in db.query(DimTiempo).all()}
529
  docs_db = {d.id_documento for d in db.query(DimOrigenDocumental).all()}
530
  users_db = {u.id for u in db.query(Users).all()}
531
 
@@ -545,6 +549,7 @@ def procesar_lote_tabular(payloads: List[ProcessSheetPayload], db: Session = Dep
545
  hechos_academic = []
546
  hechos_budget = []
547
  hechos_finance = []
 
548
 
549
  for payload in payloads:
550
  # Dimensiones requeridas
@@ -563,9 +568,18 @@ def procesar_lote_tabular(payloads: List[ProcessSheetPayload], db: Session = Dep
563
  if payload.id_modulo not in modulos_db:
564
  nuevos_modulos.append(DimModulo(id_modulo=payload.id_modulo, nombre_modulo=payload.modulo or "Modulo Generico", nombre_institucion=payload.institucion or "GiraGroup", programa=payload.programa or "General"))
565
  modulos_db.add(payload.id_modulo)
566
- if payload.id_tiempo not in tiempos_db:
567
- nuevos_tiempos.append(DimTiempo(id_tiempo=payload.id_tiempo, gestion=2026, semestre=1, mes="Mayo"))
568
- tiempos_db.add(payload.id_tiempo)
 
 
 
 
 
 
 
 
 
569
  if payload.id_documento not in docs_db:
570
  nuevos_docs.append(DimOrigenDocumental(id_documento=payload.id_documento, tipo_documento="SHEET", nombre_archivo="carga_automatica"))
571
  docs_db.add(payload.id_documento)
@@ -642,14 +656,35 @@ def procesar_lote_tabular(payloads: List[ProcessSheetPayload], db: Session = Dep
642
  monto_meta=getattr(payload, 'monto_meta', getattr(payload, 'costo', 0))
643
  ))
644
  elif area == "FINANCE":
645
- hechos_finance.append(FactSituacionFinanciera(
646
- id_estudiante=estudiante.id_estudiante,
647
- id_tiempo=payload.id_tiempo,
648
- monto_deuda=getattr(payload, 'monto_deuda', 0),
649
- cuotas_impagas=getattr(payload, 'cuotas_impagas', 0),
650
- estado_cartera=getattr(payload, 'estado_cartera', 'PENDIENTE'),
651
- tipo_alerta=getattr(payload, 'tipo_alerta', 'NINGUNA')
652
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  else: # ACADEMIC
654
  hechos_academic.append(FactRendimientoAcademico(
655
  id_estudiante=estudiante.id_estudiante, id_docente=payload.id_docente,
@@ -664,6 +699,7 @@ def procesar_lote_tabular(payloads: List[ProcessSheetPayload], db: Session = Dep
664
  if hechos_surveys: db.add_all(hechos_surveys)
665
  if hechos_budget: db.add_all(hechos_budget)
666
  if hechos_finance: db.add_all(hechos_finance)
 
667
  if hechos_academic: db.add_all(hechos_academic)
668
 
669
  db.commit()
 
149
  inscritos: Optional[int] = 0
150
  costo: Optional[float] = 0.0
151
 
 
152
  pregunta: Optional[str] = None
153
  puntuacion: Optional[float] = 0.0
154
+
155
+ # Custom fields for specific processing logic
156
+ gestion: Optional[int] = None
157
+ mes: Optional[str] = None
158
+ proyecciones_mensuales: Optional[Dict[str, float]] = None
159
 
160
  @field_validator('texto_celda')
161
  @classmethod
 
529
  # For default/generic fallback
530
  docentes_db = set(existing_docentes.values())
531
  modulos_db = {m.id_modulo for m in db.query(DimModulo).all()}
532
+ tiempos_db_list = db.query(DimTiempo).all()
533
  docs_db = {d.id_documento for d in db.query(DimOrigenDocumental).all()}
534
  users_db = {u.id for u in db.query(Users).all()}
535
 
 
549
  hechos_academic = []
550
  hechos_budget = []
551
  hechos_finance = []
552
+ hechos_cobranzas = []
553
 
554
  for payload in payloads:
555
  # Dimensiones requeridas
 
568
  if payload.id_modulo not in modulos_db:
569
  nuevos_modulos.append(DimModulo(id_modulo=payload.id_modulo, nombre_modulo=payload.modulo or "Modulo Generico", nombre_institucion=payload.institucion or "GiraGroup", programa=payload.programa or "General"))
570
  modulos_db.add(payload.id_modulo)
571
+
572
+ # Resolución dinámica de DimTiempo
573
+ gestion_val = int(payload.gestion) if getattr(payload, 'gestion', None) else 2026
574
+ mes_val = str(payload.mes).capitalize() if getattr(payload, 'mes', None) else "Mayo"
575
+ tiempo_obj = next((t for t in tiempos_db_list if t.gestion == gestion_val and t.mes.lower() == mes_val.lower()), None)
576
+ if not tiempo_obj:
577
+ new_id = max((t.id_tiempo for t in tiempos_db_list), default=0) + 1
578
+ tiempo_obj = DimTiempo(id_tiempo=new_id, gestion=gestion_val, semestre=1, mes=mes_val)
579
+ nuevos_tiempos.append(tiempo_obj)
580
+ tiempos_db_list.append(tiempo_obj)
581
+ payload.id_tiempo = tiempo_obj.id_tiempo
582
+
583
  if payload.id_documento not in docs_db:
584
  nuevos_docs.append(DimOrigenDocumental(id_documento=payload.id_documento, tipo_documento="SHEET", nombre_archivo="carga_automatica"))
585
  docs_db.add(payload.id_documento)
 
656
  monto_meta=getattr(payload, 'monto_meta', getattr(payload, 'costo', 0))
657
  ))
658
  elif area == "FINANCE":
659
+ if getattr(payload, 'proyecciones_mensuales', None):
660
+ for mes_key, monto_esp in payload.proyecciones_mensuales.items():
661
+ parts = str(mes_key).upper().replace('MONTO', '').strip().split()
662
+ mes_str = parts[0] if len(parts) > 0 else 'ENERO'
663
+ gestion_val = int(parts[1]) if len(parts) > 1 and parts[1].isdigit() else getattr(payload, 'gestion', 2024)
664
+ if not gestion_val: gestion_val = 2024
665
+
666
+ tiempo_proj = next((t for t in tiempos_db_list if t.gestion == gestion_val and t.mes.lower() == mes_str.lower()), None)
667
+ if not tiempo_proj:
668
+ new_id = max((t.id_tiempo for t in tiempos_db_list), default=0) + 1
669
+ tiempo_proj = DimTiempo(id_tiempo=new_id, gestion=gestion_val, semestre=1, mes=mes_str.capitalize())
670
+ nuevos_tiempos.append(tiempo_proj)
671
+ tiempos_db_list.append(tiempo_proj)
672
+
673
+ hechos_cobranzas.append(FactCobranzasProyectadas(
674
+ id_estudiante=estudiante.id_estudiante,
675
+ id_tiempo=tiempo_proj.id_tiempo,
676
+ monto_esperado=float(monto_esp),
677
+ estado_cobro="PENDIENTE"
678
+ ))
679
+ else:
680
+ hechos_finance.append(FactSituacionFinanciera(
681
+ id_estudiante=estudiante.id_estudiante,
682
+ id_tiempo=payload.id_tiempo,
683
+ monto_deuda=getattr(payload, 'monto_deuda', 0),
684
+ cuotas_impagas=getattr(payload, 'cuotas_impagas', 0),
685
+ estado_cartera=getattr(payload, 'estado_cartera', 'PENDIENTE'),
686
+ tipo_alerta=getattr(payload, 'tipo_alerta', 'NINGUNA')
687
+ ))
688
  else: # ACADEMIC
689
  hechos_academic.append(FactRendimientoAcademico(
690
  id_estudiante=estudiante.id_estudiante, id_docente=payload.id_docente,
 
699
  if hechos_surveys: db.add_all(hechos_surveys)
700
  if hechos_budget: db.add_all(hechos_budget)
701
  if hechos_finance: db.add_all(hechos_finance)
702
+ if hechos_cobranzas: db.add_all(hechos_cobranzas)
703
  if hechos_academic: db.add_all(hechos_academic)
704
 
705
  db.commit()