File size: 3,797 Bytes
07d0354
814c19e
061d5cb
b1d3718
b82e672
10213d3
3e4d13c
 
 
b82e672
814c19e
bf3bfc2
3e4d13c
4b30cd0
 
 
 
99ddfcc
 
814c19e
4b30cd0
07d0354
b82e672
 
 
 
a5152aa
b82e672
 
4b30cd0
 
 
 
 
 
b82e672
4b30cd0
ce4e81b
 
b82e672
a5152aa
ce4e81b
 
 
 
b82e672
ce4e81b
 
 
4b30cd0
ce4e81b
4b30cd0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce4e81b
4b30cd0
ce4e81b
4b30cd0
 
 
 
 
 
ce4e81b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import gradio as gr
import pdfplumber
import re
from transformers import LayoutLMForTokenClassification, AutoTokenizer
import torch

# Wczytanie modelu LayoutLMv3
model_name = "kryman27/layoutlmv3-finetuned"
model = LayoutLMForTokenClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)  # Automatyczne wykrycie tokenizatora

# Reguły do wykrywania NIP, kwot, dat
nip_pattern = re.compile(r'\bPL\s?\d{10}\b|\b\d{10}\b')
kwota_pattern = re.compile(r'\b\d+[\.,]?\d*\s?(PLN|zł|EUR|USD)?\b')  # Rozpoznawanie walut
data_pattern = re.compile(r'\b\d{2}\.\d{2}\.\d{4}\b')  # Format DD.MM.YYYY
payment_keywords = ["data płatności", "termin płatności", "zapłata", "zapłacono", "płatność"]
seller_keywords = ["sprzedawca", "faktura wystawiona przez", "wystawca", "nazwa firmy"]

def extract_invoice_data(pdf_file):
    with pdfplumber.open(pdf_file) as pdf:
        words, boxes, full_text = [], [], []

        for page in pdf.pages:
            extracted_words = page.extract_words()
            for word in extracted_words:
                words.append(word['text'])  # Pobieramy tekst słowa
                bbox = [int(word['x0']), int(word['top']), int(word['x1']), int(word['bottom'])]  # Zaokrąglamy wartości
                boxes.append(bbox)  # Pobieramy bounding box (pozycję słowa na stronie)

            page_text = page.extract_text()
            if page_text:
                full_text.append(page_text.lower())

    full_text = "\n".join(full_text)  # Łączymy cały tekst dokumentu

    # Tokenizacja tekstu + dodanie bounding boxes
    encoding = tokenizer.encode_plus(words, boxes=boxes, return_tensors="pt", truncation=True)

    # Predykcja modelu
    with torch.no_grad():
        outputs = model(**encoding)
    predictions = outputs.logits.argmax(-1).squeeze().tolist()

    # Przetwarzanie wyników
    entities = []
    for token, pred in zip(words, predictions):
        if pred > 0:  # Pomijamy tło
            entities.append((token, model.config.id2label[pred]))

    # 🏢 Wyszukiwanie nazwy sprzedawcy
    seller_name = [token for token, label in entities if "ORG" in label]
    
    # Jeśli model nie znalazł, szukamy w tekście
    if not seller_name:
        for line in full_text.split("\n"):
            if any(keyword in line for keyword in seller_keywords):
                seller_name = line.split(":")[-1].strip()
                break

    # 🔢 Wyszukiwanie NIP
    seller_nip = nip_pattern.search(full_text)
    
    # 💰 Wyszukiwanie kwoty całkowitej (największa kwota z walutą)
    kwoty = kwota_pattern.findall(full_text)
    kwoty = [k[0].replace(",", ".") for k in kwoty if k[0].replace(",", ".").replace(".", "").isdigit()]
    total_amount = max(map(float, kwoty), default=None) if kwoty else None

    # 📆 Wyszukiwanie daty płatności
    payment_date = None
    for line in full_text.split("\n"):
        if any(keyword in line for keyword in payment_keywords):
            date_match = data_pattern.search(line)
            if date_match:
                payment_date = date_match.group()
                break

    return {
        "Sprzedawca": " ".join(seller_name) if seller_name else "Nie znaleziono",
        "NIP": seller_nip.group() if seller_nip else "Nie znaleziono",
        "Kwota całkowita": total_amount if total_amount else "Nie znaleziono",
        "Data płatności": payment_date if payment_date else "Nie znaleziono"
    }

# Interfejs użytkownika
iface = gr.Interface(
    fn=extract_invoice_data,
    inputs=gr.File(label="Wybierz plik PDF"),
    outputs="json",
    title="Ekstrakcja danych z faktury",
    description="Prześlij plik PDF, a model zwróci dane sprzedawcy, NIP, kwotę i datę płatności."
)

if __name__ == "__main__":
    iface.launch()