110 lines
4.2 KiB
Python
110 lines
4.2 KiB
Python
import re
|
|
import pandas as pd
|
|
import os
|
|
from datetime import datetime
|
|
from PyPDF2 import PdfReader
|
|
from collections import defaultdict
|
|
|
|
# Carpeta con tus tickets PDF
|
|
ticket_folder = "tickets"
|
|
|
|
# Palabras clave que indican líneas que no deben ser procesadas
|
|
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 en el ticket (formato dd/mm/yyyy)
|
|
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 = []
|
|
# Procesar línea por línea del texto extraído
|
|
for line in text.splitlines():
|
|
# Ignorar líneas que contienen palabras clave de exclusión
|
|
if any(keyword in line for keyword in exclude_keywords):
|
|
continue
|
|
|
|
# Buscar productos con precio unitario y precio total
|
|
match = re.match(r"\d*\s?(.*?)\s+(\d+,\d{2})\s+(\d+,\d{2})", line)
|
|
if match:
|
|
nombre = match.group(1).strip().upper() # El nombre del producto
|
|
unit_price = float(match.group(2).replace(",", ".")) # Precio unitario
|
|
total_price = float(match.group(3).replace(",", ".")) # Precio total
|
|
products.append((fecha, nombre, unit_price, total_price))
|
|
else:
|
|
# En caso de no encontrar el precio unitario, solo se extrae el precio total
|
|
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
|
|
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 (puedes hacer un diccionario de equivalencias si quieres afinar más)
|
|
df["producto"] = df["producto"].str.upper().str.strip()
|
|
|
|
# Guardar detalle completo
|
|
df.to_csv("detalle_productos.csv", index=False)
|
|
|
|
# Agrupar por producto
|
|
resumen = df.groupby("producto").agg(
|
|
veces_comprado=("fecha", "count"),
|
|
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")
|
|
|
|
# Lista de compra estimada
|
|
# Calcular la frecuencia de compra y la estimación del próximo producto necesario
|
|
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 de la compra para la próxima semana
|
|
proxima_semana = datetime.now() + pd.Timedelta(weeks=1)
|
|
compra_estimacion = df[df["proxima_compra"] <= proxima_semana]
|
|
|
|
# Guardar la lista de compra estimada
|
|
compra_estimacion.to_csv("compra_estimacion.csv", index=False)
|
|
|
|
# Crear un archivo HTML visual para la lista de la compra
|
|
html = compra_estimacion[["producto", "precio_unitario", "precio_total", "proxima_compra"]].sort_values("proxima_compra").to_html(index=False)
|
|
|
|
# Guardar el archivo HTML
|
|
with open("lista_compra_estimada.html", "w") as file:
|
|
file.write(html)
|
|
|
|
print("\n✅ Análisis completado. Archivos generados:")
|
|
print("- detalle_productos.csv")
|
|
print("- resumen_productos.csv")
|
|
print("- gasto_mensual.csv")
|
|
print("- compra_estimacion.csv")
|
|
print("- lista_compra_estimada.html")
|