File size: 6,509 Bytes
07d0354
814c19e
061d5cb
b1d3718
b82e672
10213d3
3e4d13c
 
218a320
814c19e
f4a79f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99ddfcc
 
814c19e
f4a79f7
 
 
 
 
 
 
 
 
 
 
 
ce4e81b
f4a79f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce4e81b
f4a79f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce4e81b
f4a79f7
 
 
 
 
 
 
 
 
 
 
 
 
4b30cd0
f4a79f7
 
 
 
 
 
 
ce4e81b
f4a79f7
 
 
ce4e81b
f4a79f7
 
 
 
 
 
 
ce4e81b
f4a79f7
ce4e81b
 
 
 
 
 
f4a79f7
ce4e81b
 
7489f6d
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import gradio as gr
import pdfplumber
import re
from transformers import LayoutLMForTokenClassification, AutoTokenizer
import torch

model_name = "kryman27/layoutlmv3-finetuned"
model = LayoutLMForTokenClassification.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)

# Wzorce regex dla nowych p贸l
nip_pattern = re.compile(r'\b(?:PL\s?)?\d{10}\b')
invoice_number_pattern = re.compile(r'Faktura\s*(?:VAT)?\s*(?:nr\.?|#)\s*([\w\-/]+)', re.IGNORECASE)
sale_date_pattern = re.compile(r'Data\s+wystawienia[:\s]*([\d]{2}[.\-/][\d]{2}[.\-/][\d]{4})', re.IGNORECASE)
delivery_date_pattern = re.compile(r'Data\s+dostawy[:\s]*([\d]{2}[.\-/][\d]{2}[.\-/][\d]{4})', re.IGNORECASE)
payment_date_pattern = re.compile(r'(?:Termin\s+p艂atno艣ci|Data\s+p艂atno艣ci)[:\s]*([\d]{2}[.\-/][\d]{2}[.\-/][\d]{4})', re.IGNORECASE)
order_number_pattern = re.compile(r'Zam贸wienie\s*Nr[:\s]*([\w\-/]+)', re.IGNORECASE)
order_date_pattern = re.compile(r'Data\s+zam贸wienia[:\s]*([\d]{2}[.\-/][\d]{2}[.\-/][\d]{4})', re.IGNORECASE)
sale_order_pattern = re.compile(r'Zlecenie\s+sprzeda偶y\s*Nr[:\s]*([\w\-/]+)', re.IGNORECASE)
payment_amount_pattern = re.compile(r'(?:Kwota\s+zap艂acona)[:\s]*([\d.,]+)', re.IGNORECASE)
payment_method_pattern = re.compile(r'(?:Forma\s+p艂atno艣ci)[:\s]*([\w/]+)', re.IGNORECASE)

def extract_section(text, section_title):
    pattern = re.compile(rf'{section_title}:(.*?)(?=\n\S|$)', re.IGNORECASE | re.DOTALL)
    match = pattern.search(text)
    return match.group(1).strip() if match else None

def extract_invoice_data(pdf_file):
    with pdfplumber.open(pdf_file) as pdf:
        full_text = "\n".join(page.extract_text() for page in pdf.pages if page.extract_text())
    
    # Wyodr臋bnienie sekcji na podstawie tytu艂贸w
    sprzedawca_section = extract_section(full_text, "Sprzedawca")
    nabywca_section = extract_section(full_text, "Nabywca")
    
    sprzedawca = {}
    nabywca = {}
    faktura = {}
    platnosc = {}
    pozycje = []  # Do implementacji ekstrakcji tabelarycznej
    podsumowanie = {}

    # Ekstrakcja danych Sprzedawcy
    if sprzedawca_section:
        lines = sprzedawca_section.splitlines()
        sprzedawca['Nazwa'] = lines[0].strip() if lines else "Nie znaleziono"
        nip_match = nip_pattern.search(sprzedawca_section)
        sprzedawca['NIP'] = nip_match.group() if nip_match else "Nie znaleziono"
        bdo_match = re.search(r'BDO[:\s]*([\w\d]+)', sprzedawca_section, re.IGNORECASE)
        sprzedawca['Numer Rejestracyjny BDO'] = bdo_match.group(1) if bdo_match else "Nie znaleziono"
        sprzedawca['Adres'] = lines[1].strip() if len(lines) > 1 else "Nie znaleziono"
        telefon_match = re.search(r'tel\.?[:\s]*([\+\d\s()-]+)', sprzedawca_section, re.IGNORECASE)
        sprzedawca['Telefon'] = telefon_match.group(1).strip() if telefon_match else "Nie znaleziono"
        fax_match = re.search(r'fax\.?[:\s]*([\+\d\s()-]+)', sprzedawca_section, re.IGNORECASE)
        sprzedawca['Fax'] = fax_match.group(1).strip() if fax_match else "Nie znaleziono"
    else:
        sprzedawca = {
            "Nazwa": "Nie znaleziono",
            "NIP": "Nie znaleziono",
            "Numer Rejestracyjny BDO": "Nie znaleziono",
            "Adres": "Nie znaleziono",
            "Telefon": "Nie znaleziono",
            "Fax": "Nie znaleziono"
        }

    # Ekstrakcja danych Nabywcy
    if nabywca_section:
        lines = nabywca_section.splitlines()
        nabywca['Nazwa'] = lines[0].strip() if lines else "Nie znaleziono"
        nip_match = nip_pattern.search(nabywca_section)
        nabywca['NIP'] = nip_match.group() if nip_match else "Nie podano"
        nabywca['Adres'] = lines[1].strip() if len(lines) > 1 else "Nie znaleziono"
        klient_match = re.search(r'Nr\s+Klienta[:\s]*([\w\d]+)', nabywca_section, re.IGNORECASE)
        nabywca['Nr Klienta'] = klient_match.group(1) if klient_match else "Nie znaleziono"
    else:
        nabywca = {
            "Nazwa": "Nie znaleziono",
            "NIP": "Nie podano",
            "Adres": "Nie znaleziono",
            "Nr Klienta": "Nie znaleziono"
        }

    # Ekstrakcja danych faktury
    invoice_number_match = invoice_number_pattern.search(full_text)
    faktura['Numer'] = invoice_number_match.group(1) if invoice_number_match else "Nie znaleziono"
    sale_date_match = sale_date_pattern.search(full_text)
    faktura['Data Wystawienia'] = sale_date_match.group(1) if sale_date_match else "Nie znaleziono"
    delivery_date_match = delivery_date_pattern.search(full_text)
    faktura['Data Dostawy'] = delivery_date_match.group(1) if delivery_date_match else "Nie znaleziono"
    order_number_match = order_number_pattern.search(full_text)
    faktura['Zam贸wienie Nr'] = order_number_match.group(1) if order_number_match else "Nie znaleziono"
    order_date_match = order_date_pattern.search(full_text)
    faktura['Data Zam贸wienia'] = order_date_match.group(1) if order_date_match else "Nie znaleziono"
    sale_order_match = sale_order_pattern.search(full_text)
    faktura['Zlecenie Sprzeda偶y Nr'] = sale_order_match.group(1) if sale_order_match else "Nie znaleziono"

    # Ekstrakcja danych p艂atno艣ci
    payment_date_match = payment_date_pattern.search(full_text)
    platnosc['Termin Zap艂aty'] = payment_date_match.group(1) if payment_date_match else "Nie znaleziono"
    payment_method_match = payment_method_pattern.search(full_text)
    platnosc['Forma Zap艂aty'] = payment_method_match.group(1) if payment_method_match else "Nie znaleziono"
    payment_amount_match = payment_amount_pattern.search(full_text)
    platnosc['Kwota Zap艂acona'] = float(payment_amount_match.group(1).replace(',', '.')) if payment_amount_match else "Nie znaleziono"

    # Ekstrakcja podsumowania (przyk艂adowo)
    podsumowanie_match = re.search(r'Razem[:\s]*([\d.,]+)', full_text)
    podsumowanie['Suma Brutto'] = float(podsumowanie_match.group(1).replace(',', '.')) if podsumowanie_match else "Nie znaleziono"

    result = {
        "Sprzedawca": sprzedawca,
        "Nabywca": nabywca,
        "Faktura": faktura,
        "P艂atno艣膰": platnosc,
        "Pozycje": pozycje,
        "Podsumowanie": podsumowanie
    }
    return result

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 narz臋dzie zwr贸ci szczeg贸艂owe dane faktury."
)

#UI start
if __name__ == "__main__":
    iface.launch()