commit 65897afcf81c0468d21511671b62b790febbcee1 Author: admin Date: Mon May 19 15:09:34 2025 +0000 Primer commit diff --git a/1234.png b/1234.png new file mode 100644 index 0000000..2ff32f3 Binary files /dev/null and b/1234.png differ diff --git a/fact.py b/fact.py new file mode 100644 index 0000000..8439386 --- /dev/null +++ b/fact.py @@ -0,0 +1,134 @@ +import tkinter as tk +from tkinter import filedialog, messagebox +from PIL import Image +import pytesseract +import hashlib +import sqlite3 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import rsa, padding +from cryptography.hazmat.primitives.serialization import load_pem_private_key +import os +import re +import base64 +import datetime +import xml.etree.ElementTree as ET + +# Configuracion de OCR +pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # Cambia si es necesario + +# Crear clave RSA para firmar +clave_privada = rsa.generate_private_key(public_exponent=65537, key_size=2048) +clave_publica = clave_privada.public_key() + +# Crear base de datos +conn = sqlite3.connect("facturas.db") +c = conn.cursor() +c.execute('''CREATE TABLE IF NOT EXISTS facturas ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + nombre_archivo TEXT, + datos_extraidos TEXT, + hash TEXT, + firma BLOB, + csv TEXT, + fecha TEXT, + nif_emisor TEXT, + nif_receptor TEXT, + total REAL +)''') +conn.commit() + +# Funciones del programa +def seleccionar_archivo(): + ruta = filedialog.askopenfilename(filetypes=[("PDF o Imagen", "*.png;*.jpg;*.jpeg;*.tiff;*.bmp")]) + if ruta: + texto = extraer_texto(ruta) + nif_emisor = extraer_nif(texto, emisor=True) + nif_receptor = extraer_nif(texto, emisor=False) + total = extraer_total(texto) + fecha = extraer_fecha(texto) + hash_valor = generar_hash(texto) + firma = firmar_texto(texto) + csv = generar_csv(hash_valor) + guardar_en_db(ruta, texto, hash_valor, firma, csv, fecha, nif_emisor, nif_receptor, total) + generar_facturae(ruta, nif_emisor, nif_receptor, fecha, total, csv) + messagebox.showinfo("Éxito", "Factura procesada y guardada.") + mostrar_resultado(texto, hash_valor, csv, fecha, nif_emisor, nif_receptor, total) + +def extraer_texto(ruta): + imagen = Image.open(ruta) + texto = pytesseract.image_to_string(imagen, lang='spa') + return texto + +def extraer_nif(texto, emisor=True): + nif_pattern = r'\b[A-Z]?[0-9]{7,8}[A-Z]?\b' + nifs = re.findall(nif_pattern, texto) + return nifs[0] if emisor and nifs else (nifs[1] if len(nifs) > 1 else "") + +def extraer_total(texto): + total_pattern = r'Total[:\s]*([0-9]+[.,][0-9]{2})' + match = re.search(total_pattern, texto, re.IGNORECASE) + return float(match.group(1).replace(',', '.')) if match else 0.0 + +def extraer_fecha(texto): + fecha_pattern = r'(\d{2}[\/\-]\d{2}[\/\-]\d{4})' + match = re.search(fecha_pattern, texto) + return match.group(1) if match else datetime.date.today().strftime("%d/%m/%Y") + +def generar_hash(texto): + return hashlib.sha256(texto.encode('utf-8')).hexdigest() + +def firmar_texto(texto): + firma = clave_privada.sign( + texto.encode('utf-8'), + padding.PKCS1v15(), + hashes.SHA256() + ) + return firma + +def generar_csv(hash_valor): + return "CSV-" + hash_valor[:10] + +def guardar_en_db(nombre_archivo, texto, hash_valor, firma, csv, fecha, nif_emisor, nif_receptor, total): + c.execute("""INSERT INTO facturas + (nombre_archivo, datos_extraidos, hash, firma, csv, fecha, nif_emisor, nif_receptor, total) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""", + (nombre_archivo, texto, hash_valor, firma, csv, fecha, nif_emisor, nif_receptor, total)) + conn.commit() + +def generar_facturae(nombre_archivo, emisor, receptor, fecha, total, csv): + root = ET.Element("Facturae") + ET.SubElement(root, "Emisor").text = emisor + ET.SubElement(root, "Receptor").text = receptor + ET.SubElement(root, "Fecha").text = fecha + ET.SubElement(root, "Total").text = str(total) + ET.SubElement(root, "CSV").text = csv + + tree = ET.ElementTree(root) + nombre_xml = os.path.splitext(os.path.basename(nombre_archivo))[0] + "_facturae.xml" + tree.write(nombre_xml) + +def mostrar_resultado(texto, hash_valor, csv, fecha, nif_emisor, nif_receptor, total): + resultado.delete("1.0", tk.END) + resultado.insert(tk.END, f"📄 Texto extraído:\n{texto}\n") + resultado.insert(tk.END, f"\n🔐 Hash: {hash_valor}\n") + resultado.insert(tk.END, f"🧾 CSV generado: {csv}\n") + resultado.insert(tk.END, f"📅 Fecha: {fecha}\n") + resultado.insert(tk.END, f"🏢 NIF Emisor: {nif_emisor}\n") + resultado.insert(tk.END, f"👤 NIF Receptor: {nif_receptor}\n") + resultado.insert(tk.END, f"💰 Total: {total} €\n") + +# GUI +ventana = tk.Tk() +ventana.title("Digitalizador de Facturas AEAT - v2.0") +ventana.geometry("800x600") + +titulo = tk.Label(ventana, text="Digitalizador de Facturas (Cumplimiento AEAT)", font=("Arial", 16)) +titulo.pack(pady=10) + +boton = tk.Button(ventana, text="📤 Seleccionar factura", command=seleccionar_archivo, bg="#4CAF50", fg="white", font=("Arial", 12)) +boton.pack(pady=20) + +resultado = tk.Text(ventana, wrap="word", height=20) +resultado.pack(padx=10, pady=10, fill="both", expand=True) + +ventana.mainloop() diff --git a/facturas.db b/facturas.db new file mode 100644 index 0000000..606f54f Binary files /dev/null and b/facturas.db differ diff --git a/modelo-factura-es-moderno-rojo-750px.png b/modelo-factura-es-moderno-rojo-750px.png new file mode 100644 index 0000000..102a986 Binary files /dev/null and b/modelo-factura-es-moderno-rojo-750px.png differ