vsersion 2
This commit is contained in:
145
fac1.1.py
Normal file
145
fac1.1.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
from tkinter import *
|
||||||
|
from tkinter import filedialog, messagebox
|
||||||
|
from PIL import Image, ImageTk
|
||||||
|
import pytesseract
|
||||||
|
import re
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
import datetime
|
||||||
|
import hashlib
|
||||||
|
import qrcode
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
# Configuración del path de Tesseract
|
||||||
|
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
|
||||||
|
|
||||||
|
# Base de datos de solo lectura (una vez creada)
|
||||||
|
DB_PATH = "facturas.db"
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS facturas (
|
||||||
|
hash TEXT PRIMARY KEY,
|
||||||
|
datos TEXT,
|
||||||
|
qr_path TEXT,
|
||||||
|
fecha TEXT)''')
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
def seleccionar_archivo():
|
||||||
|
ruta = filedialog.askopenfilename(filetypes=[("Imágenes", "*.png;*.jpg;*.jpeg")])
|
||||||
|
if ruta:
|
||||||
|
mostrar_factura(ruta)
|
||||||
|
texto = extraer_texto(ruta)
|
||||||
|
datos = extraer_datos(texto)
|
||||||
|
mostrar_datos(datos)
|
||||||
|
hash_val, qr_path = guardar_en_db(datos)
|
||||||
|
mostrar_hash_qr(hash_val, qr_path)
|
||||||
|
guardar_datos_json(datos)
|
||||||
|
|
||||||
|
def mostrar_factura(ruta):
|
||||||
|
imagen = Image.open(ruta)
|
||||||
|
imagen = imagen.resize((500, 700))
|
||||||
|
img_tk = ImageTk.PhotoImage(imagen)
|
||||||
|
|
||||||
|
img_label.config(image=img_tk)
|
||||||
|
img_label.image = img_tk
|
||||||
|
|
||||||
|
def extraer_texto(ruta):
|
||||||
|
imagen = Image.open(ruta)
|
||||||
|
return pytesseract.image_to_string(imagen, lang='spa')
|
||||||
|
|
||||||
|
def extraer_datos(texto):
|
||||||
|
return {
|
||||||
|
"NIF Emisor": extraer_nif_emisor(texto),
|
||||||
|
"NIF Receptor": extraer_nif_receptor(texto),
|
||||||
|
"Fecha": extraer_fecha(texto),
|
||||||
|
"Total": extraer_total(texto),
|
||||||
|
"Texto Completo": texto
|
||||||
|
}
|
||||||
|
|
||||||
|
def mostrar_datos(datos):
|
||||||
|
for widget in datos_frame.winfo_children():
|
||||||
|
widget.destroy()
|
||||||
|
|
||||||
|
for campo, valor in datos.items():
|
||||||
|
Label(datos_frame, text=f"{campo}:", font=("Arial", 10, "bold")).pack(anchor="w")
|
||||||
|
Label(datos_frame, text=valor, font=("Arial", 10), wraplength=350, justify=LEFT).pack(anchor="w")
|
||||||
|
Label(datos_frame, text="").pack()
|
||||||
|
|
||||||
|
def mostrar_hash_qr(hash_val, qr_path):
|
||||||
|
Label(datos_frame, text="Hash SHA-256:", font=("Arial", 10, "bold")).pack(anchor="w")
|
||||||
|
Label(datos_frame, text=hash_val, font=("Arial", 8), wraplength=350, justify=LEFT, fg="blue").pack(anchor="w")
|
||||||
|
|
||||||
|
qr_img = Image.open(qr_path)
|
||||||
|
qr_img = qr_img.resize((150, 150))
|
||||||
|
qr_tk = ImageTk.PhotoImage(qr_img)
|
||||||
|
|
||||||
|
qr_label = Label(datos_frame, image=qr_tk)
|
||||||
|
qr_label.image = qr_tk
|
||||||
|
qr_label.pack(anchor="w", pady=10)
|
||||||
|
|
||||||
|
def guardar_datos_json(datos):
|
||||||
|
fecha_actual = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
nombre_archivo = f"factura_{fecha_actual}.json"
|
||||||
|
with open(nombre_archivo, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(datos, f, ensure_ascii=False, indent=4)
|
||||||
|
|
||||||
|
def guardar_en_db(datos):
|
||||||
|
datos_str = json.dumps(datos, ensure_ascii=False)
|
||||||
|
hash_val = hashlib.sha256(datos_str.encode("utf-8")).hexdigest()
|
||||||
|
|
||||||
|
qr = qrcode.make(hash_val)
|
||||||
|
qr_path = f"qr_{hash_val[:8]}.png"
|
||||||
|
qr.save(qr_path)
|
||||||
|
|
||||||
|
conn = sqlite3.connect(DB_PATH)
|
||||||
|
c = conn.cursor()
|
||||||
|
try:
|
||||||
|
c.execute("INSERT INTO facturas (hash, datos, qr_path, fecha) VALUES (?, ?, ?, ?)",
|
||||||
|
(hash_val, datos_str, qr_path, datos.get("Fecha", "")))
|
||||||
|
conn.commit()
|
||||||
|
except sqlite3.IntegrityError:
|
||||||
|
messagebox.showinfo("Info", "La factura ya ha sido registrada (hash duplicado).")
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
return hash_val, qr_path
|
||||||
|
|
||||||
|
def extraer_nif_emisor(texto):
|
||||||
|
match = re.search(r'\b[A-Z0-9]{8,9}\b', texto)
|
||||||
|
return match.group() if match else "No encontrado"
|
||||||
|
|
||||||
|
def extraer_nif_receptor(texto):
|
||||||
|
match = re.findall(r'\b[A-Z0-9]{8,9}\b', texto)
|
||||||
|
if len(match) > 1:
|
||||||
|
return match[1]
|
||||||
|
return "No encontrado"
|
||||||
|
|
||||||
|
def extraer_fecha(texto):
|
||||||
|
match = re.search(r'\d{2}/\d{2}/\d{4}', texto)
|
||||||
|
return match.group() if match else "No encontrada"
|
||||||
|
|
||||||
|
def extraer_total(texto):
|
||||||
|
match = re.search(r'(\d+[.,]\d{2})\s*[€€]', texto)
|
||||||
|
return match.group(1) + " €" if match else "No encontrado"
|
||||||
|
|
||||||
|
# GUI principal
|
||||||
|
init_db()
|
||||||
|
root = Tk()
|
||||||
|
root.title("Visor de Factura + OCR")
|
||||||
|
root.geometry("900x720")
|
||||||
|
|
||||||
|
main_frame = Frame(root)
|
||||||
|
main_frame.pack(fill=BOTH, expand=True)
|
||||||
|
|
||||||
|
img_label = Label(main_frame)
|
||||||
|
img_label.pack(side=LEFT, padx=10, pady=10)
|
||||||
|
|
||||||
|
datos_frame = Frame(main_frame)
|
||||||
|
datos_frame.pack(side=RIGHT, fill=Y, padx=10, pady=10)
|
||||||
|
|
||||||
|
btn = Button(root, text="Seleccionar Factura", command=seleccionar_archivo)
|
||||||
|
btn.pack(pady=10)
|
||||||
|
|
||||||
|
root.mainloop()
|
||||||
7
factura_20250327_082633.json
Normal file
7
factura_20250327_082633.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"NIF Emisor": "No encontrado",
|
||||||
|
"NIF Receptor": "No encontrado",
|
||||||
|
"Fecha": "29/01/2019",
|
||||||
|
"Total": "199.65 €",
|
||||||
|
"Texto Completo": "Factura ES-001\n\nRojo Polo Paella Inc.\n\nCarretera Muelle 38\n37531 Ávila, Ávila\n\nFacturar a\n\nLeda Villareal\nVirgen Blanca 63\n08759 Burgos, Burgos\n\nEnviar a Fecha 29/01/2019\nLeda Villareal N* de pedido 1730/2019\nCercas Bajas 68\n\nFecha 29/01/2019\n\n47300 Cádiz, Cádiz\nvencimiento\n\nCant. Descripción Precio unitario Importe\n1 Talla pequeña traje de luces en rojo 100.00 100.00\n2 Mui grande churrolito 25.00 50.00\n3 Equipaje de Fútbol 5.00 15.00\nSubtotal 165.00\nIVA 21.0% 34.65\nTotal 199.65 €\n\n4\n\nCondiciones y forma de pago\n\nEl pago se realizará en un plazo de 15 días\n\nBanco Santander\nIBAN: ES12 3456 7891\n'SWIFT/BIC: ABCDESM1XXX\n"
|
||||||
|
}
|
||||||
7
factura_20250327_082838.json
Normal file
7
factura_20250327_082838.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"NIF Emisor": "No encontrado",
|
||||||
|
"NIF Receptor": "No encontrado",
|
||||||
|
"Fecha": "29/01/2019",
|
||||||
|
"Total": "199.65 €",
|
||||||
|
"Texto Completo": "Factura ES-001\n\nRojo Polo Paella Inc.\n\nCarretera Muelle 38\n37531 Ávila, Ávila\n\nFacturar a\n\nLeda Villareal\nVirgen Blanca 63\n08759 Burgos, Burgos\n\nEnviar a Fecha 29/01/2019\nLeda Villareal N* de pedido 1730/2019\nCercas Bajas 68\n\nFecha 29/01/2019\n\n47300 Cádiz, Cádiz\nvencimiento\n\nCant. Descripción Precio unitario Importe\n1 Talla pequeña traje de luces en rojo 100.00 100.00\n2 Mui grande churrolito 25.00 50.00\n3 Equipaje de Fútbol 5.00 15.00\nSubtotal 165.00\nIVA 21.0% 34.65\nTotal 199.65 €\n\n4\n\nCondiciones y forma de pago\n\nEl pago se realizará en un plazo de 15 días\n\nBanco Santander\nIBAN: ES12 3456 7891\n'SWIFT/BIC: ABCDESM1XXX\n"
|
||||||
|
}
|
||||||
7
factura_20250327_082904.json
Normal file
7
factura_20250327_082904.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"NIF Emisor": "No encontrado",
|
||||||
|
"NIF Receptor": "No encontrado",
|
||||||
|
"Fecha": "29/01/2019",
|
||||||
|
"Total": "199.65 €",
|
||||||
|
"Texto Completo": "Factura ES-001\n\nRojo Polo Paella Inc.\n\nCarretera Muelle 38\n37531 Ávila, Ávila\n\nFacturar a\n\nLeda Villareal\nVirgen Blanca 63\n08759 Burgos, Burgos\n\nEnviar a Fecha 29/01/2019\nLeda Villareal N* de pedido 1730/2019\nCercas Bajas 68\n\nFecha 29/01/2019\n\n47300 Cádiz, Cádiz\nvencimiento\n\nCant. Descripción Precio unitario Importe\n1 Talla pequeña traje de luces en rojo 100.00 100.00\n2 Mui grande churrolito 25.00 50.00\n3 Equipaje de Fútbol 5.00 15.00\nSubtotal 165.00\nIVA 21.0% 34.65\nTotal 199.65 €\n\n4\n\nCondiciones y forma de pago\n\nEl pago se realizará en un plazo de 15 días\n\nBanco Santander\nIBAN: ES12 3456 7891\n'SWIFT/BIC: ABCDESM1XXX\n"
|
||||||
|
}
|
||||||
7
factura_20250327_083023.json
Normal file
7
factura_20250327_083023.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"NIF Emisor": "No encontrado",
|
||||||
|
"NIF Receptor": "No encontrado",
|
||||||
|
"Fecha": "No encontrada",
|
||||||
|
"Total": "199.65 €",
|
||||||
|
"Texto Completo": "Factura ES-001\n\nRojo Polo Paella Inc.\n\nCarretera Muelle 38\n37531 Ávila, Ávila\n\nLeda Villareal Leda Villareal N? de pedido 1730/2019\n1 Talla pequeña traje de luces en rojo 100.00 100.00\n2 Mui grande churrolito. 25.00 50.00\n3 Equipaje de Fútbol 5.00 15.00\n\nSubtotal 165.00\nIVA 21.0% 34.65\nTotal 199.65 €\n\nCondiciones y forma de pago\n\nEl pago se realizará en un plazo de 15 días\n\nBanco Santander\nIBAN: ES12 3456 7891\n'SWIFT/BIC: ABCDESM1XXX\n"
|
||||||
|
}
|
||||||
7
factura_20250329_091909.json
Normal file
7
factura_20250329_091909.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"NIF Emisor": "No encontrado",
|
||||||
|
"NIF Receptor": "No encontrado",
|
||||||
|
"Fecha": "29/01/2019",
|
||||||
|
"Total": "199.65 €",
|
||||||
|
"Texto Completo": "Factura ES-001\n\nRojo Polo Paella Inc.\n\nCarretera Muelle 38\n37531 Ávila, Ávila\n\nFacturar a\n\nLeda Villareal\nVirgen Blanca 63\n08759 Burgos, Burgos\n\nEnviar a Fecha 29/01/2019\nLeda Villareal N* de pedido 1730/2019\nCercas Bajas 68\n\nFecha 29/01/2019\n\n47300 Cádiz, Cádiz\nvencimiento\n\nCant. Descripción Precio unitario Importe\n1 Talla pequeña traje de luces en rojo 100.00 100.00\n2 Mui grande churrolito 25.00 50.00\n3 Equipaje de Fútbol 5.00 15.00\nSubtotal 165.00\nIVA 21.0% 34.65\nTotal 199.65 €\n\n4\n\nCondiciones y forma de pago\n\nEl pago se realizará en un plazo de 15 días\n\nBanco Santander\nIBAN: ES12 3456 7891\n'SWIFT/BIC: ABCDESM1XXX\n"
|
||||||
|
}
|
||||||
BIN
facturas.db
BIN
facturas.db
Binary file not shown.
1
modelo-factura-es-moderno-rojo-750px_facturae.xml
Normal file
1
modelo-factura-es-moderno-rojo-750px_facturae.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<Facturae><Emisor /><Receptor /><Fecha>29/01/2019</Fecha><Total>165.0</Total><CSV>CSV-5ee435e194</CSV></Facturae>
|
||||||
BIN
qr_1dbac13a.png
Normal file
BIN
qr_1dbac13a.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
qr_9e851b53.png
Normal file
BIN
qr_9e851b53.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Reference in New Issue
Block a user