feat: Enhance CSV cleaning service with new endpoints for CSV analysis and preview functionality. Introduce support for job management linked to extraction batches, and update the cleaning rules structure. Add new utility functions for handling CSV data and improve documentation for clarity on usage and available endpoints.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
"""Aplicación de reglas seleccionadas sobre un DataFrame."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any, Optional
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from .cop_mod import _apply_cop_mod_split, merge_moderadora_config
|
||||
from .documents import _apply_doc_id_split_columns
|
||||
from .notas import _apply_nota_extract_columns
|
||||
from .rules import get_rule_fn, get_rule_name
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def apply_rules(
|
||||
df: pd.DataFrame,
|
||||
rules_per_column: dict[str, list[str]],
|
||||
*,
|
||||
cop_mod_fecha_column: Optional[dict[str, str]] = None,
|
||||
cop_mod_config: Optional[dict[str, Any]] = None,
|
||||
) -> tuple[pd.DataFrame, list[str]]:
|
||||
"""Aplica las reglas seleccionadas a cada columna.
|
||||
|
||||
`rules_per_column` es un dict de `columna -> lista de IDs de reglas en el
|
||||
orden a aplicar`. La regla `cop_mod_split` se difiere a una segunda pasada
|
||||
tras el resto, para que la columna de fecha pueda normalizarse antes.
|
||||
|
||||
`cop_mod_fecha_column`: mapa columna de importe -> nombre de columna Fecha Servicio.
|
||||
`cop_mod_config`: opcional; puede incluir ``moderadora_by_year`` (dict año → lista).
|
||||
"""
|
||||
result = df.copy()
|
||||
log: list[str] = []
|
||||
|
||||
moderadora_years = merge_moderadora_config(cop_mod_config)
|
||||
|
||||
def _run_rules_for_column(col: str, rule_ids: list[str]) -> None:
|
||||
if not rule_ids:
|
||||
return
|
||||
if col not in result.columns:
|
||||
log.append(f"[WARN] Columna no encontrada: {col}")
|
||||
return
|
||||
split_has_homologation = (
|
||||
"doc_id_split_tipo_numero" in rule_ids and "doc_type_homologate" in rule_ids
|
||||
)
|
||||
for rule_id in rule_ids:
|
||||
if rule_id == "doc_id_split_tipo_numero":
|
||||
try:
|
||||
_apply_doc_id_split_columns(
|
||||
result, col, log, homologate_type=split_has_homologation
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.exception("Error aplicando regla %s a %s", rule_id, col)
|
||||
log.append(f"[ERROR] '{col}' regla '{rule_id}': {exc}")
|
||||
continue
|
||||
if rule_id == "nota_paciente_autorizacion":
|
||||
try:
|
||||
_apply_nota_extract_columns(result, col, log)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.exception("Error aplicando regla %s a %s", rule_id, col)
|
||||
log.append(f"[ERROR] '{col}' regla '{rule_id}': {exc}")
|
||||
continue
|
||||
if rule_id == "doc_type_homologate" and split_has_homologation:
|
||||
continue
|
||||
fn = get_rule_fn(rule_id)
|
||||
if fn is None:
|
||||
log.append(f"[WARN] Regla desconocida '{rule_id}' en columna '{col}'")
|
||||
continue
|
||||
try:
|
||||
result[col] = fn(result[col])
|
||||
log.append(f"[OK] '{col}' <- {get_rule_name(rule_id)}")
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.exception("Error aplicando regla %s a %s", rule_id, col)
|
||||
log.append(f"[ERROR] '{col}' regla '{rule_id}': {exc}")
|
||||
|
||||
# Fase 1: todas las reglas excepto cop_mod_split
|
||||
for col, rule_ids in rules_per_column.items():
|
||||
filtered = [r for r in rule_ids if r != "cop_mod_split"]
|
||||
_run_rules_for_column(col, filtered)
|
||||
|
||||
# Fase 2: Separa COP/MOD sobre el DataFrame ya transformado
|
||||
fecha_map = cop_mod_fecha_column or {}
|
||||
for col, rule_ids in rules_per_column.items():
|
||||
if "cop_mod_split" not in rule_ids:
|
||||
continue
|
||||
fecha_col = fecha_map.get(col)
|
||||
if not fecha_col:
|
||||
log.append(
|
||||
f"[WARN] COP/MOD en '{col}': indique la columna «Fecha Servicio» en la tarjeta; se omite."
|
||||
)
|
||||
continue
|
||||
try:
|
||||
_apply_cop_mod_split(
|
||||
result,
|
||||
col,
|
||||
fecha_col,
|
||||
log,
|
||||
moderadora_by_year=moderadora_years,
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
logger.exception("Error aplicando COP/MOD a %s", col)
|
||||
log.append(f"[ERROR] '{col}' regla 'cop_mod_split': {exc}")
|
||||
|
||||
return result, log
|
||||
Reference in New Issue
Block a user