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>
This commit is contained in:
1 parent
99a587c4da
commit
c2503745bf
18 files changed
+647
-862
No files matched your search
+43
-12
@@ -2,9 +2,11 @@ import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
from logger_manager import get_logger
|
||||
|
||||
# ============================================================================
|
||||
load_dotenv()
|
||||
logger = get_logger(__name__)
|
||||
|
||||
HANA_HOST = os.getenv("HANA_HOST", "")
|
||||
HANA_PORT = int(os.getenv("HANA_PORT", 30015))
|
||||
@@ -27,7 +29,7 @@ def get_connection():
|
||||
password=HANA_PASSWORD
|
||||
)
|
||||
except Exception as e:
|
||||
print(f" ❌ Error conectando a HANA: {e}")
|
||||
logger.error(f"Error conectando a HANA: {e}")
|
||||
return None
|
||||
return _conn
|
||||
|
||||
@@ -49,6 +51,7 @@ def obtener_pendientes() -> list[dict]:
|
||||
"LicTradNum",
|
||||
"FolioPref",
|
||||
"FolioNum",
|
||||
"ObjType",
|
||||
"U_PGX_REPIMP" "urlPDF",
|
||||
"U_PGX_PDF" "tienePDF",
|
||||
"U_PGX_REPIMPXML" "urlXML",
|
||||
@@ -56,9 +59,35 @@ def obtener_pendientes() -> list[dict]:
|
||||
FROM "{HANA_SCHEMA}".OPCH
|
||||
WHERE ("U_PGX_PDF" = 'N' OR "U_PGX_XML" = 'N')
|
||||
AND EXTRACT(YEAR FROM "DocDate") = 2026
|
||||
AND "Indicator" IN ('01', '02','08')
|
||||
AND "Indicator" IN ('01','02','03')
|
||||
AND "CANCELED" = 'N'
|
||||
ORDER BY EXTRACT(MONTH FROM "DocDate") DESC
|
||||
AND "LicTradNum" NOT IN ('20100047218','20100130204','20100053455')
|
||||
AND SUBSTRING("FolioPref", 1, 1) NOT BETWEEN '0' AND '9'
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
"DocEntry",
|
||||
"DocNum",
|
||||
"DocDate",
|
||||
EXTRACT(MONTH FROM "DocDate") "Mes",
|
||||
"Indicator",
|
||||
"LicTradNum",
|
||||
"FolioPref",
|
||||
"FolioNum",
|
||||
"ObjType",
|
||||
"U_PGX_REPIMP" "urlPDF",
|
||||
"U_PGX_PDF" "tienePDF",
|
||||
"U_PGX_REPIMPXML" "urlXML",
|
||||
"U_PGX_XML" "tieneXML"
|
||||
FROM "{HANA_SCHEMA}".ORPC
|
||||
WHERE ("U_PGX_PDF" = 'N' OR "U_PGX_XML" = 'N')
|
||||
AND EXTRACT(YEAR FROM "DocDate") = 2026
|
||||
AND "Indicator" IN ('07')
|
||||
AND "CANCELED" = 'N'
|
||||
AND "LicTradNum" NOT IN ('20100047218','20100130204','20100053455')
|
||||
AND SUBSTRING("FolioPref", 1, 1) NOT BETWEEN '0' AND '9'
|
||||
|
||||
"""
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(query)
|
||||
@@ -68,45 +97,47 @@ def obtener_pendientes() -> list[dict]:
|
||||
result = [dict(zip(columns, row)) for row in rows]
|
||||
return result
|
||||
except Exception as e:
|
||||
print(f" ❌ Error en query HANA: {e}")
|
||||
logger.error(f"Error en query HANA: {e}")
|
||||
return []
|
||||
|
||||
# ============================================================================
|
||||
def marcar_pdf_descargado(docentry: int, url: str, ruta: str):
|
||||
def marcar_pdf_descargado(docentry: int, url: str, ruta: str, obj_type: int = 18):
|
||||
conn = get_connection()
|
||||
if not conn:
|
||||
return False
|
||||
tabla = "ORPC" if int(obj_type) == 19 else "OPCH"
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(f"""
|
||||
UPDATE "{HANA_SCHEMA}".OPCH
|
||||
UPDATE "{HANA_SCHEMA}".{tabla}
|
||||
SET "U_PGX_PDF" = 'Y'
|
||||
WHERE "DocEntry" = ?
|
||||
""", (docentry))
|
||||
""", (docentry,))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ❌ Error actualizando PDF HANA: {e}")
|
||||
logger.error(f"Error actualizando PDF HANA: {e}")
|
||||
return False
|
||||
|
||||
# ============================================================================
|
||||
def marcar_xml_descargado(docentry: int, url: str, ruta: str):
|
||||
def marcar_xml_descargado(docentry: int, url: str, ruta: str, obj_type: int = 18):
|
||||
conn = get_connection()
|
||||
if not conn:
|
||||
return False
|
||||
tabla = "ORPC" if int(obj_type) == 19 else "OPCH"
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(f"""
|
||||
UPDATE "{HANA_SCHEMA}".OPCH
|
||||
UPDATE "{HANA_SCHEMA}".{tabla}
|
||||
SET "U_PGX_XML" = 'Y'
|
||||
WHERE "DocEntry" = ?
|
||||
""", (docentry))
|
||||
""", (docentry,))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f" ❌ Error actualizando XML HANA: {e}")
|
||||
logger.error(f"Error actualizando XML HANA: {e}")
|
||||
return False
|
||||
|
||||
# ============================================================================
|
||||
|
||||
Reference in new issue
Block a user