Files
GeorgeandClaude Sonnet 5 c2503745bf Reemplaza logging por consola/archivo, agrega historial de intentos y soporte para notas de crédito
- Nuevo logger_manager.py (reemplaza logger_utilities.py): logging con formato de árbol,
  rotación diaria a sunat.log, y consola por stdout (antes iba por stderr y se duplicaba
  en logs/error.log del launchd).
- Nuevo historial_manager.py: registra cada intento de consulta/descarga en historial.db
  para auditoría, con limpieza automática de registros de más de 180 días.
- consulta_cpe.py: corrige el id de notas de crédito/débito (usa F7/F8, no 07/08) y
  agrega reintentos ante errores 5xx.
- hana_manager.py: suma consulta a ORPC para notas de crédito (Indicator 07) y soporte
  de ObjType para actualizar la tabla correcta (OPCH/ORPC) al marcar PDF/XML descargado.
- gestor_fallas.py / main.py: propagan objtype end-to-end y dejan constancia de cada
  intento en historial_manager.
- Elimina login_api.py y reporte_fallas.py (código no usado / script manual sin uso reciente).
- Actualiza .gitignore (sunat-venv/, historial.db*) y docs/ para reflejar el estado real
  del proyecto.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-31 12:31:48 -05:00

2.8 KiB

Módulos

Archivo Función
main.py Daemon orquestador. Bucle infinito con horarios configurables (scheduler.json), obtiene token, consulta HANA, procesa pendientes (nuevos + reintentos).
get_token_headless.py Login headless via Firefox real. Sin ventana visible.
get_token.py Login SOL via Playwright (headless=False). Navega menú → extrae JWT de sessionStorage['SUNAT.token'].
consulta_cpe.py Consulta API REST api-cpe.sunat.gob.pe. Retorna (data, status_code). Lanza TokenExpiredError en 401.
hana_manager.py Conexión HANA vía hdbcli. Consulta pendientes en OPCH, actualiza flags de descarga.
gestor_fallas.py SQLite fallas_descarga.db. Registro de fallas con conteo de intentos y backoff progresivo (0min → 5min → 15min → ... → 12h, máx 20).
historial_manager.py SQLite historial.db. Registra cada intento de consulta/descarga (éxito o falla) para auditoría; limpia registros de más de 180 días. Incluye CLI (python historial_manager.py --ruc/--serie/--numero/--tipo) para buscar intentos.
logger_manager.py Logging con formato de árbol (indentado por tareas anidadas) a consola + archivo. Rotación diaria en logs/sunat_YYYY-MM-DD.log, limpieza automática de logs con más de 7 días.
smb_manager.py Monta recurso SMB (mount_smbfs/mount.cifs/net use) y sincroniza PDF/XML al NAS. Limpia JSON/ZIP temporales.
scheduler.json Horarios activos (HORARIOS) y días de la semana en que corre el daemon (DIAS_ACTIVOS). Editable sin tocar código.
token.json Token JWT auto-generado con expiración.
.env Credenciales HANA y SUNAT.

Flujo

  1. main.py verifica día/horario (scheduler.json) → renueva token si expiró (get_token_headless → get_token.py headless=False)
  2. obtener_pendientes() trae todos los documentos de OPCH donde tienePDF='N' o tieneXML='N'
  3. Separa en nuevos (no están en fallas DB) y reintentos (fallas pendientes con backoff cumplido)
  4. Por cada doc:
    • consultar_cpe() → si 401, renueva token y reintenta
    • Si falla (500/404/etc) → registrar_falla() con backoff progresivo
    • Si OK → descargar_archivo() (XML + PDF + CDR)
    • marcar_pdf_descargado() / marcar_xml_descargado() actualizan HANA
    • Si era reintento exitoso → eliminar_falla()
    • registrar_intento() deja constancia del resultado en historial.db
  5. sincronizar_a_smb() monta NAS (si no está montado), copia PDF/XML via rsync (Mac/Linux) o shutil.move (Windows), y elimina JSON/ZIP temporales de descargas/
  6. Espera intervalo configurado (según scheduler.json, ej. 5 min modo rápido, 30 min/1 h modo full) y repite

Al arrancar, main.py también corre mantenimiento: limpiar_logs_antiguos(dias=7) y limpiar_historial_antiguo(dias=180).