Primer commit

This commit is contained in:
2025-05-19 15:09:34 +00:00
commit 65897afcf8
4 changed files with 134 additions and 0 deletions

BIN
1234.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

134
fact.py Normal file
View File

@@ -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()

BIN
facturas.db Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB