File size: 2,276 Bytes
71b8475
 
 
 
 
198a2a8
71b8475
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import tempfile
import os
import shutil
from pathlib import Path
from parse_invoices import read_msg, parse_lpo_html, init_or_load_workbook, append_row, get_excel_path

def process_msg_files(files):
    if not files:
        return None, "No files uploaded."

    with tempfile.TemporaryDirectory() as tmpdir:
        tmpdir = Path(tmpdir)

        # Save uploaded files to temp folder
        for f in files:
            shutil.copy(f.name, tmpdir / Path(f.name).name)

        # Run parser
        excel_path = get_excel_path(tmpdir)
        wb, ws = init_or_load_workbook(excel_path)
        next_row = ws.max_row + 1

        log_lines = []
        for msg_path in sorted(tmpdir.glob('*.msg')):
            try:
                subject, html_bytes = read_msg(msg_path)
                if not html_bytes:
                    log_lines.append(f"⚠️ {msg_path.name} — no HTML body")
                    continue
                fields = parse_lpo_html(html_bytes)
                row_data = {'subject': subject, 'filename': msg_path.name, **fields}
                missing = [k for k, v in fields.items() if v is None]
                status = 'PARTIAL' if missing else 'OK'
                append_row(ws, row_data, next_row, status=status)
                next_row += 1
                log_lines.append(f"✅ {msg_path.name} — LPO:{fields['lpo_number']} | Inv:{fields['inv_number']} | Amount:{fields['inv_amount']}")
            except Exception as e:
                log_lines.append(f"❌ {msg_path.name} — ERROR: {e}")

        wb.save(excel_path)
        wb.close()

        # Copy excel to a stable output path Gradio can serve
        out_path = Path(tempfile.mktemp(suffix='.xlsx'))
        shutil.copy(excel_path, out_path)

        return str(out_path), "\n".join(log_lines)


demo = gr.Interface(
    fn=process_msg_files,
    inputs=gr.File(
        file_count="multiple",
        file_types=[".msg"],
        label="Upload .msg files"
    ),
    outputs=[
        gr.File(label="Download Excel"),
        gr.Textbox(label="Processing Log", lines=15)
    ],
    title="LPO Invoice Parser",
    description="Upload one or more Outlook .msg LPO emails. Get back a formatted Excel with LPO #, Ref No, Inv #, and Amount."
)

demo.launch()