import re import pandas as pd import os from datetime import datetime, timedelta from PyPDF2 import PdfReader from collections import defaultdict # Carpeta con tus tickets PDF ticket_folder = "tickets" def extract_data_from_pdf(file_path): reader = PdfReader(file_path) text = "" for page in reader.pages: text += page.extract_text() + "\n" 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(): match = re.match(r"\d*\s?(.*?)\s+(\d+,\d{2})\s+(\d+,\d{2})", line) if match: nombre = match.group(1).strip().upper() unit_price = float(match.group(2).replace(",", ".")) total_price = float(match.group(3).replace(",", ".")) products.append((fecha, nombre, unit_price, total_price)) else: match_simple = re.match(r"(.*?)\s+(\d+,\d{2})$", line) if match_simple: nombre = match_simple.group(1).strip().upper() total_price = float(match_simple.group(2).replace(",", ".")) products.append((fecha, nombre, None, total_price)) return products # Recolectar todos los productos de todos los tickets def load_and_process_data(): 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", "producto", "precio_unitario", "precio_total"] df = pd.DataFrame(datos, columns=columnas) df.dropna(subset=["fecha"], inplace=True) # Normalizar nombres de producto df["producto"] = df["producto"].str.upper().str.strip() return df # Calcular la frecuencia de compra y la fecha estimada de la próxima compra def calculate_purchase_estimates(df): # Calcular el tiempo entre compras para cada producto df["diferencia_dias"] = df.groupby("producto")["fecha"].diff().dt.days # Calcular la frecuencia de compra (promedio de días entre compras) frecuencia_compra = df.groupby("producto")["diferencia_dias"].mean().reset_index() # Estimación de la duración de los productos (cuánto duran en casa) frecuencia_compra["proxima_compra_estimado"] = df["fecha"].max() + pd.to_timedelta(frecuencia_compra["diferencia_dias"], unit="D") # Ahora seleccionamos los productos que más frecuentemente compras frecuencia_compra["producto"] = frecuencia_compra["producto"].str.title() # Capitalizar el nombre del producto frecuencia_compra["fecha_estimada_proxima_compra"] = frecuencia_compra["proxima_compra_estimado"].dt.strftime("%d/%m/%Y") return frecuencia_compra # Generar la lista de la compra semanal def generate_weekly_shopping_list(frecuencia_compra): today = datetime.today() # Calcular la fecha del próximo jueves days_until_next_thursday = (3 - today.weekday()) % 7 next_thursday = today + timedelta(days=days_until_next_thursday) # Filtrar los productos cuya próxima compra se estima para la próxima semana productos_estimados = frecuencia_compra[frecuencia_compra["proxima_compra_estimado"] <= next_thursday] # Generar la lista de la compra en formato HTML html_content = """ Lista de la Compra Semanal

Lista de la Compra Semanal (Próximo Jueves)

""" # Añadir filas con los productos for _, row in productos_estimados.iterrows(): html_content += f""" """ html_content += """
Producto Días Promedio entre Compras Fecha Estimada de la Próxima Compra
{row['producto']} {row['diferencia_dias']:.0f} {row['fecha_estimada_proxima_compra']}
""" # Guardar el archivo HTML file_name = f"lista_compra_semanal_{next_thursday.strftime('%d_%m_%Y')}.html" with open(file_name, "w", encoding="utf-8") as file: file.write(html_content) print(f"\n✅ Página HTML generada: {file_name}") # Función para actualizar la lista de la compra después de agregar un nuevo ticket def update_shopping_list(): # Cargar y procesar los datos df = load_and_process_data() # Calcular las estimaciones de la compra frecuencia_compra = calculate_purchase_estimates(df) # Generar la lista de la compra para la próxima semana (jueves) generate_weekly_shopping_list(frecuencia_compra) # Llamar a la función para actualizar la lista de la compra update_shopping_list()