import re import pandas as pd import os from datetime import datetime from PyPDF2 import PdfReader # Carpeta con los tickets PDF ticket_folder = "tickets" # Palabras clave que indican líneas que no hay que procesar exclude_keywords = [ "TARJETA BANCARIA", "IVA BASE IMPONIBLE", "CUOTA", "TOTAL", "SE ADMITEN DEVOLUCIONES CON TICKET", "N.C", "AUT", "AID", "Verificado por dispositivo", "Visa Credit", "IMPORTE", "TARJ. BANCARIA" ] def extract_data_from_pdf(file_path): reader = PdfReader(file_path) text = "" for page in reader.pages: text += page.extract_text() + "\n" # Buscar la fecha date_match = re.search(r"(\d{2}/\d{2}/\d{4})", text) fecha = datetime.strptime(date_match.group(1), "%d/%m/%Y") if date_match else None products = [] for line in text.splitlines(): if any(keyword in line for keyword in exclude_keywords): continue # Coincide con líneas tipo: "2 ROLLO HOGAR DOBLE 2,35 4,70" match = re.match(r"(\d+)\s+(.*?)\s+(\d+,\d{2})\s+(\d+,\d{2})$", line) if match: cantidad = int(match.group(1)) producto = match.group(2).strip().upper() precio_unitario = float(match.group(3).replace(",", ".")) precio_total = float(match.group(4).replace(",", ".")) products.append((fecha, cantidad, producto, precio_unitario, precio_total)) continue # Coincide con líneas tipo: "1 CROISSANT RELL CACAO 1,90" match_simple = re.match(r"(\d+)\s+(.*?)\s+(\d+,\d{2})$", line) if match_simple: cantidad = int(match_simple.group(1)) producto = match_simple.group(2).strip().upper() precio_total = float(match_simple.group(3).replace(",", ".")) precio_unitario = precio_total / cantidad products.append((fecha, cantidad, producto, round(precio_unitario, 2), precio_total)) continue return products # Recolectar todos los datos de los tickets datos = [] for file in os.listdir(ticket_folder): if file.endswith(".pdf"): path = os.path.join(ticket_folder, file) datos.extend(extract_data_from_pdf(path)) # Crear DataFrame columnas = ["fecha", "cantidad", "producto", "precio_unitario", "precio_total"] df = pd.DataFrame(datos, columns=columnas) df.dropna(subset=["fecha"], inplace=True) # Guardar detalle completo df.to_csv("detalle_productos.csv", index=False) # Agrupar por producto resumen = df.groupby("producto").agg( veces_comprado=("fecha", "count"), total_unidades=("cantidad", "sum"), gasto_total=("precio_total", "sum"), primera_vez=("fecha", "min"), ultima_vez=("fecha", "max") ).sort_values("gasto_total", ascending=False) resumen.to_csv("resumen_productos.csv") # Gasto mensual df["mes"] = df["fecha"].dt.to_period("M") gasto_mensual = df.groupby("mes")["precio_total"].sum() gasto_mensual.to_csv("gasto_mensual.csv") # Calcular próxima compra estimada por media de días entre compras df["dias_entre_compras"] = df.groupby("producto")["fecha"].diff().dt.days df["promedio_dias_entre_compras"] = df.groupby("producto")["dias_entre_compras"].transform("mean") df["proxima_compra"] = df["fecha"] + pd.to_timedelta(df["promedio_dias_entre_compras"], unit='D') # Crear la lista estimada para la próxima compra (esta semana) proxima_semana = datetime.now() + pd.Timedelta(days=7) compra_estimacion = df[df["proxima_compra"] <= proxima_semana] # Guardar lista estimada compra_estimacion.to_csv("compra_estimacion.csv", index=False) # Generar HTML visual html = compra_estimacion[["producto", "cantidad", "precio_unitario", "precio_total", "proxima_compra"]].sort_values("proxima_compra").to_html(index=False) with open("lista_compra_estimada.html", "w") as file: file.write(html) print("\n✅ Todo listo. Archivos generados:") print("- detalle_productos.csv") print("- resumen_productos.csv") print("- gasto_mensual.csv") print("- compra_estimacion.csv") print("- lista_compra_estimada.html")