import pdfplumber import re import os ######################################################## def extraer_texto_pdf(ruta_pdf): """Extrae todo el texto de un PDF usando pdfplumber.""" texto_completo = "" try: with pdfplumber.open(ruta_pdf) as pdf: for page in pdf.pages: texto_completo += page.extract_text() + "\n" return texto_completo except Exception as e: print(f" ⚠️ Error leyendo PDF {ruta_pdf}: {e}") return "" ######################################################## def extraer_ruc(texto): """Busca un RUC (11 dígitos, empieza con 10 o 20) en el texto.""" # Intentamos buscar patrones de RUC: RUC 2060... o R.U.C. 2060... patrones = [ r'R\.?U\.?C\.?\s*[:\-\s]\s*((?:10|20)\d{9})', # R.U.C: 20... r'\b((?:10|20)\d{9})\b' # 11 dígitos sueltos que empiecen con 10 o 20 ] for patron in patrones: match = re.search(patron, texto, re.IGNORECASE) if match: return match.group(1) return "N/A" ######################################################## def extraer_tipo_documento(texto): """Identifica el tipo de documento SUNAT basándose en el texto usando regex multilínea.""" t = texto.upper() patrones = { "01": [r'FACTURA\s+(ELECTR[OÓ]NICA|DE\s+VENTA)', r'FACTURA'], "03": [r'BOLETA\s+DE\s+VENTA', r'BOLETA\s+ELECTR[OÓ]NICA'], "07": [r'NOTA\s+DE\s+CR[EÉ]DITO'], "08": [r'NOTA\s+DE\s+D[EÉ]BITO'], "14": [r'RECIBO\s+POR\s+HONORARIOS'], "09": [r'GU[IÍ]A\s+DE\s+REMISI[OÓ]N'] } for tipo, regex_list in patrones.items(): for p in regex_list: if re.search(p, t, re.IGNORECASE | re.MULTILINE): return tipo return "99" ######################################################## def extraer_serie_numero(texto): """Busca la serie y número (ej. F001-123 o F001-0000123).""" # Patrón común: [FBE][A-Z0-9]{3}-\d+ patron = re.search(r'\b([FBE][A-Z0-9]{3})\s*-\s*(\d+)\b', texto) if patron: return f"{patron.group(1)}-{patron.group(2)}" # Fallback para casos donde no hay guión o hay espacios raros patron_alt = re.search(r'([FBE][A-Z0-9]{3})\s+(\d{1,10})', texto) if patron_alt: return f"{patron_alt.group(1)}-{patron_alt.group(2)}" return "No encontrado" ######################################################## def obtener_datos_pdf(ruta_pdf): """Orquestador para extraer metadata de un PDF.""" texto = extraer_texto_pdf(ruta_pdf) if not texto: return {"valido": False, "error": "No se pudo extraer texto"} return { "valido": True, "tipo_doc": extraer_tipo_documento(texto), "ruc": extraer_ruc(texto), "id": extraer_serie_numero(texto) } ########################################################