import os import sys import json import glob sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) from sunat_schema import extraer_datos_xml def renombrar_xml(ruta_actual: str, data: dict, carpeta: str) -> str | None: """Renombra el XML a {prefijo}{ruc}-{tipo}-{serie}-{numero}.xml y retorna la nueva ruta. Si es un CDR (ApplicationResponse), el prefijo es 'CDR-'.""" if not data: return None prefijo = "CDR-" if data.get("es_cdr") else "" nombre = f"{prefijo}{data.get('ruc_emisor', '')}-{data.get('tipo', '')}-{data.get('serie', '')}-{data.get('numero', '')}.xml" destino = os.path.join(carpeta, nombre) if destino != ruta_actual: if os.path.exists(destino): os.remove(destino) os.rename(ruta_actual, destino) return destino CARPETA_BASE = os.path.join(os.path.dirname(__file__), "correos_prueba") def procesar_carpetas(): carpetas = sorted( [d for d in os.listdir(CARPETA_BASE) if os.path.isdir(os.path.join(CARPETA_BASE, d))] ) total = 0 for carpeta in carpetas: ruta_carpeta = os.path.join(CARPETA_BASE, carpeta) archivos_xml = sorted( os.path.join(ruta_carpeta, f) for f in os.listdir(ruta_carpeta) if f.lower().endswith(".xml") and os.path.isfile(os.path.join(ruta_carpeta, f)) ) if not archivos_xml: continue correlativo = carpeta.split("_")[0] documentos = [] for xml_path in archivos_xml: print(f"πŸ“„ {carpeta}/{os.path.basename(xml_path)}") data = extraer_datos_xml(xml_path) if data: ruta_xml = renombrar_xml(xml_path, data, ruta_carpeta) data["ruta_xml"] = ruta_xml or xml_path data["ruta_pdf"] = None if data.get("es_cdr"): print(f" β”œβ”€β”€ ℹ️ {data.get('serie','?')}-{data.get('numero','?')} (CDR) β€” omitido del resultado") continue documentos.append(data) print(f" β”œβ”€β”€ βœ… {data.get('serie','?')}-{data.get('numero','?')} ({data.get('tipo_descripcion','?')})") else: print(f" β”œβ”€β”€ ℹ️ No es factura 01 ni guΓ­a 31") if documentos: # Post-procesamiento # 1. Distribuir documentos_referencia (tipo 09 y 31) a cada lΓ­nea for doc in documentos: if doc.get("tipo") != "01": continue refs_09 = [r for r in doc.get("documentos_referencia", []) if r.get("tipo") == "09"] refs_31 = [r for r in doc.get("documentos_referencia", []) if r.get("tipo") == "31"] for i, linea in enumerate(doc.get("lineas", [])): if linea.get("guias_remision"): continue if i < len(refs_09): es_ultima = i == len(doc["lineas"]) - 1 if es_ultima: linea["guias_remision"] = [dict(r) for r in refs_09[i:]] else: linea["guias_remision"] = [dict(refs_09[i])] if not linea.get("guia_transportista") and i < len(refs_31): linea["guia_transportista"] = dict(refs_31[i]) # 2. Resolver GREs desde guΓ­as de transporte (tipo 31 β†’ tipo 09) guia_lookup = {} for doc in documentos: if doc.get("tipo") in ("31", "09"): guia_lookup[(doc["tipo"], doc["serie"], doc["numero"])] = doc for doc in documentos: if doc.get("tipo") != "01": continue for ref in doc.get("documentos_referencia", []): if ref["tipo"] == "31": guia_doc = guia_lookup.get(("31", ref["serie"], ref["numero"])) if guia_doc: gre_list = [g for g in guia_doc.get("documentos_referencia", []) if g.get("tipo") == "09"] if gre_list: for i, linea in enumerate(doc.get("lineas", [])): if not linea.get("guias_remision"): es_ultima = i == len(doc["lineas"]) - 1 if es_ultima: linea["guias_remision"] = gre_list[i:] elif i < len(gre_list): linea["guias_remision"] = [gre_list[i]] if not linea.get("guia_transportista"): linea["guia_transportista"] = dict(ref) ruta_json = os.path.join(ruta_carpeta, f"xml_resultado_{correlativo}.json") with open(ruta_json, "w", encoding="utf-8") as f: json.dump(documentos, f, ensure_ascii=False, indent=2) print(f" └── πŸ’Ύ Guardado: xml_resultado_{correlativo}.json ({len(documentos)} doc(s))") total += len(documentos) print(f"\n{'='*60}") print(f"πŸ“Š Total documentos XML procesados: {total}") if __name__ == "__main__": procesar_carpetas()