diff --git a/KPC/_process_batch_v0.py b/KPC/_process_batch_v0.py new file mode 100644 index 0000000..71b65b7 --- /dev/null +++ b/KPC/_process_batch_v0.py @@ -0,0 +1,71 @@ +"""_process_batch_v0.py — DOČASNÉ: dávka 2 faktur (T-Mobile osobní, Perlička ordinace).""" +import sys +from datetime import date +from pathlib import Path +sys.stdout.reconfigure(encoding="utf-8") +sys.path.insert(0, r"U:\ordinaceprojekt") +import dropbox, msal, requests +from Knihovny.telegram_notify import zeptej_se_telegram, posli_telegram + +today = date.today(); ddmmyy = today.strftime("%d%m%y"); fdate = today.strftime("%Y-%m-%d") + +payments = [ + dict(name="T-Mobile", payer="2100046291", acct="19-2235210247", hal=60920, + vs="9953395180", bank="0100", ks="0000", ss="", av="faktura T-Mobile 20MAY-19JUN2026", + summary="T-Mobile 06-2026", mailbox="vladimir.buzalka@buzalka.cz", + msg_id="AAMkADY2MzQ0N2JkLWE4NjAtNDNjYS05OTVlLTQxYjhkYWVlZmY1NQBGAAAAAACkV0glv2dZRLb1sPnwFvdvBwAzGo7b-cvrRoXjMGfWnzDsAAAAAAEMAAAzGo7b-cvrRoXjMGfWnzDsAALtAR6DAAA="), + dict(name="Perlicka", payer="2800046620", acct="2603293964", hal=322000, + vs="2026474", bank="2010", ks="0000", ss="", av="Perlicka fa 2026474", + summary="Perlička fa 2026474", mailbox="ordinace@buzalka.cz", + msg_id="AQMkADYxOTE5ZTYwLTg2MWItNDNmOC04MWE5LTczZjM0NmJmMTRlYwBGAAADlMSYEfdwGUe6ACarqZh2ygcAszvBQpZaWUKlscfbC8_jxwAAAgEMAAAAszvBQpZaWUKlscfbC8_jxwABaPXXzgAAAA=="), +] + +def build(p): + ssfield = p["ss"] if p["ss"] else " " + item = f"{p['acct']} {str(p['hal']).zfill(12)} {p['vs']} {p['bank']}{p['ks']} {ssfield} AV:{p['av']}" + lines = ["UHL1"+ddmmyy+" "*20+"0"*28, "1 1501 000000 2010", + f"2 000000-{p['payer']} {str(p['hal']).zfill(14)} {ddmmyy}", item, "3 +", "5 +"] + return ("\r\n".join(lines)+"\r\n").encode("ascii") + +for p in payments: + p["data"] = build(p) + p["fname"] = f"{fdate} KPC k platbě [{p['summary']}].kpc" + print(f"=== {p['fname']} ({len(p['data'])} B) ===") + print(p["data"].decode("ascii").replace("\r\n","\\r\\n\n"), end="") + print() + +msg = ( + "💳 Návrh plateb (KPC agent) — 2 faktury\n\n" + "1) T-Mobile 609,20 Kč → 19-2235210247/0100, VS 9953395180 (z osobního)\n" + "2) Perlička 3 220,00 Kč → 2603293964/2010, VS 2026474 (z ordinace)\n\n" + "FIO: obojí nezaplaceno ✅ (Perlička = nový dodavatel)\n\n" + "Vytvořit oba KPC a nahrát do Dropboxu? Odpověz: ano / ne" +) +print(">> Potvrzeno v chatu (ano) — pokračuji bez Telegram dotazu.") + +# Dropbox + Graph +env = {} +for line in Path(r"U:\PythonProject\Janssen\EmailsImport\.env").read_text(encoding="utf-8").splitlines(): + line=line.strip() + if "=" in line and not line.startswith("#"): + k,v=line.split("=",1); env[k.strip()]=v.strip() +dbx = dropbox.Dropbox(app_key=env["DROPBOX_APP_KEY"], app_secret=env["DROPBOX_APP_SECRET"], + oauth2_refresh_token=env["DROPBOX_APP_REFRESH_TOKEN"]) +TENANT="7d269944-37a4-43a1-8140-c7517dc426e9"; CID="4b222bfd-78c9-4239-a53f-43006b3ed07f" +SECRET="Txg8Q~MjhocuopxsJyJBhPmDfMxZ2r5WpTFj1dfk" +app=msal.ConfidentialClientApplication(CID,authority=f"https://login.microsoftonline.com/{TENANT}",client_credential=SECRET) +tok=app.acquire_token_for_client(scopes=["https://graph.microsoft.com/.default"]) +H={"Authorization":f"Bearer {tok['access_token']}","Content-Type":"application/json"} +out_dir = Path(__file__).parent/"output"; out_dir.mkdir(exist_ok=True) + +for p in payments: + (out_dir/p["fname"]).write_bytes(p["data"]) + res = dbx.files_upload(p["data"], f"/!!!Days/Downloads Z230/{p['fname']}", + mode=dropbox.files.WriteMode.add, autorename=True) + print(f"NAHRÁNO → {res.path_display}") + rp = requests.patch(f"https://graph.microsoft.com/v1.0/users/{p['mailbox']}/messages/{p['msg_id']}", + headers=H, json={"categories":["KPCzpracovánoClaudem"]}, timeout=30) + print(f"PATCH {p['name']} ({p['mailbox']}): {rp.status_code}", "" if rp.ok else rp.text[:200]) + +posli_telegram("✅ KPC vytvořeno a nahráno (2):\n• T-Mobile 609,20 Kč (osobní)\n• Perlička 3 220 Kč (ordinace)\nV bankingu stačí podepsat.") +print(">> HOTOVO.") diff --git a/KPC/_process_ordinace_faktury_v0.py b/KPC/_process_ordinace_faktury_v0.py new file mode 100644 index 0000000..0a58e87 --- /dev/null +++ b/KPC/_process_ordinace_faktury_v0.py @@ -0,0 +1,114 @@ +"""_process_ordinace_faktury_v0.py — DOČASNÉ: KPC per dodavatel z 8 ordinačních faktur. +Z PDF vytáhne účet+VS (Claude), cross-check účtu proti FIO historii + částky proti názvu, +sestaví per-dodavatel KPC (kpc_format) z ordinace a nahraje do Dropboxu. +""" +import importlib, json, os, re, subprocess, sys +from datetime import date +from pathlib import Path + +sys.stdout.reconfigure(encoding="utf-8") +for mod, pkg in (("fitz", "PyMuPDF"), ("requests", "requests"), ("dropbox", "dropbox")): + try: importlib.import_module(mod) + except ImportError: subprocess.check_call([sys.executable, "-m", "pip", "install", "--quiet", pkg]) +import fitz, requests, dropbox # noqa: E402 +sys.path.insert(0, r"U:\ordinaceprojekt\EmailAgent") +import kpc_format # noqa: E402 + +def _load_env(p): + p = Path(p) + if p.exists(): + for line in p.read_text(encoding="utf-8").splitlines(): + line = line.strip() + if "=" in line and not line.startswith("#"): + k, v = line.split("=", 1); os.environ.setdefault(k.strip(), v.strip().strip('"').strip("'")) +_load_env(r"U:\ordinaceprojekt\Medevio\.env") +_load_env(r"U:\PythonProject\Janssen\EmailsImport\.env") + +PAYER = "2800046620" # ordinace +DIR = r"U:\Dropbox\Ordinace\!!MUDr. Michaela Buzalková s.r.o\Prosek\#040 Faktury přijaté" +# (dodavatel, číslo faktury, částka z názvu, soubor) +ENTRIES = [ + ("MEDEVIO", "321799", 2497.58, "2026-06-22 Faktura MEDEVIO 321799 [Medevio tarif Ústředna Pokročilá Plus] [2497.58 CZK].pdf"), + ("Poliklinika Prosek", "91260794", 464.64, "2026-06-15 Faktura Poliklinika Prosek 91260794 [sterilizace, telefonní poplatek] [464.64 CZK].pdf"), + ("Ptáček", "202605002", 3632.10, "2026-06-12 Faktura Ptáček 202605002 [vakcína FSME-IMMUN 0.5 ml] [3632.10 CZK].pdf"), + ("Poliklinika Prosek", "96260214", 28363.00, "2026-06-01 Faktura Poliklinika Prosek 96260214 [nájemné a služby] [28363.00 CZK].pdf"), + ("Ptáček", "202604906", 1214.08, "2026-06-10 Faktura Ptáček 202604906 [vakcína ADACEL] [1214.08 CZK].pdf"), + ("QuickSeal", "110606255", 2620.00, "2026-06-01 Faktura QuickSeal 110606255 [VivaDiag Hydroxyvitamin D3 testy, poštovné] [2620.00 CZK].pdf"), + ("ASKER", "261103225", 339.00, "2026-06-01 Faktura ASKER 261103225 [kontejner Yannick 1.5 l] [339.00 CZK].pdf"), + ("Ptáček", "202604570", 9235.20, "2026-05-29 Faktura Ptáček 202604570 [vakcíny Adacel, Vaqta, Havrix] [9235.20 CZK].pdf"), +] +# Účty dodavatelů z FIO historie (cross-check proti záměně/chybě extrakce) +FIO_ACCOUNTS = { + "MEDEVIO": ("2701907026", "2010"), + "Poliklinika Prosek": ("1387720540", "2700"), + "Ptáček": ("220205630", "0300"), + "QuickSeal": ("197638875", "0300"), + "ASKER": ("2913796399", "0800"), +} + +PROMPT = """Z TEXTU faktury vytáhni BANKOVNÍ ÚDAJE K PLATBĚ. Vrať POUZE JSON: +{"predcisli":"" nebo číslice, "cislo_uctu":"číslo účtu příjemce bez kódu banky", + "smer_kod":"4místný kód banky", "vs":"variabilní symbol k platbě", "castka_kc":číslo, + "ss":"specifický symbol nebo prázdné"} +TEXT FAKTURY: +%(t)s +""" + +def claude(text): + r = requests.post("https://api.anthropic.com/v1/messages", + headers={"x-api-key": os.environ["ANTHROPIC_API_KEY"], "anthropic-version": "2023-06-01", + "content-type": "application/json"}, + json={"model": "claude-opus-4-8", "max_tokens": 400, + "messages": [{"role": "user", "content": PROMPT % {"t": text[:14000]}}]}, timeout=90) + r.raise_for_status() + t = r.json()["content"][0]["text"] + return json.loads(re.search(r"\{.*\}", t, re.S).group(0)) + +ddmmrr = date.today().strftime("%d%m%y") +groups = {} # dodavatel -> [Polozka] +report = [] +for dod, fakt, castka_nazev, fname in ENTRIES: + txt = "".join(p.get_text() for p in fitz.open(str(Path(DIR) / fname))) + d = claude(txt) + ucet = re.sub(r"\D", "", str(d.get("cislo_uctu", ""))) + smer = str(d.get("smer_kod", "")).strip() + vs = str(d.get("vs", "")).strip() + castka = float(d.get("castka_kc") or 0) + flags = [] + fio_u, fio_b = FIO_ACCOUNTS.get(dod, ("", "")) + if fio_u and ucet != fio_u: + flags.append(f"ÚČET ≠ FIO ({ucet} vs {fio_u})") + if fio_b and smer != fio_b: + flags.append(f"BANKA ≠ FIO ({smer} vs {fio_b})") + if abs(castka - castka_nazev) > 0.01: + flags.append(f"ČÁSTKA ≠ název ({castka} vs {castka_nazev})") + status = "OK" if not flags else "FLAG: " + "; ".join(flags) + report.append((dod, fakt, castka_nazev, ucet, smer, vs, status)) + if not flags: + av = kpc_format._ascii(f"{dod} fa {fakt}") + groups.setdefault(dod, []).append(kpc_format.Polozka( + ucet=kpc_format.fmt_account(ucet, d.get("predcisli", "")), + halere=round(castka_nazev * 100), vs=vs, smer_kod=smer, + ks="0000", ss=str(d.get("ss") or ""), av=av)) + +print("=== EXTRAKCE + CROSS-CHECK ===") +for dod, fakt, c, ucet, smer, vs, status in report: + print(f"{dod:20} fa {fakt:11} {c:>10.2f} → {ucet}/{smer} VS {vs:12} [{status}]") + +# Dropbox +dbx = dropbox.Dropbox(app_key=os.environ["DROPBOX_APP_KEY"], app_secret=os.environ["DROPBOX_APP_SECRET"], + oauth2_refresh_token=os.environ["DROPBOX_APP_REFRESH_TOKEN"]) +out_dir = Path(__file__).parent / "output"; out_dir.mkdir(exist_ok=True) +fdate = date.today().strftime("%Y-%m-%d") + +print("\n=== KPC PER DODAVATEL ===") +for dod, items in groups.items(): + data = kpc_format.build_kpc(PAYER, items, ddmmrr=ddmmrr) + summary = f"{dod}" + (f" {len(items)} faktury" if len(items) > 1 else f" fa {[e[1] for e in report if e[0]==dod][0]}") + fname = f"{fdate} KPC k platbě [{summary}].kpc" + (out_dir / fname).write_bytes(data) + print(f"\n--- {fname} ---") + print(data.decode("ascii").replace("\r\n", "\\r\\n\n"), end="") + res = dbx.files_upload(data, f"/!!!Days/Downloads Z230/{fname}", + mode=dropbox.files.WriteMode.add, autorename=True) + print(f"NAHRÁNO → {res.path_display}") diff --git a/KPC/output/2026-06-22 KPC k platbě [Perlička fa 2026474].kpc b/KPC/output/2026-06-22 KPC k platbě [Perlička fa 2026474].kpc new file mode 100644 index 0000000..44f604a --- /dev/null +++ b/KPC/output/2026-06-22 KPC k platbě [Perlička fa 2026474].kpc @@ -0,0 +1,6 @@ +UHL1220626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000000322000 220626 +2603293964 000000322000 2026474 20100000 AV:Perlicka fa 2026474 +3 + +5 + diff --git a/KPC/output/2026-06-22 KPC k platbě [T-Mobile 06-2026].kpc b/KPC/output/2026-06-22 KPC k platbě [T-Mobile 06-2026].kpc new file mode 100644 index 0000000..fce8ff2 --- /dev/null +++ b/KPC/output/2026-06-22 KPC k platbě [T-Mobile 06-2026].kpc @@ -0,0 +1,6 @@ +UHL1220626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2100046291 00000000060920 220626 +19-2235210247 000000060920 9953395180 01000000 AV:faktura T-Mobile 20MAY-19JUN2026 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [ASKER fa 261103225].kpc b/KPC/output/2026-06-23 KPC k platbě [ASKER fa 261103225].kpc new file mode 100644 index 0000000..19aa0dc --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [ASKER fa 261103225].kpc @@ -0,0 +1,6 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000000033900 230626 +2913796399 000000033900 261103225 08000000 AV:ASKER fa 261103225 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [MEDEVIO fa 321799].kpc b/KPC/output/2026-06-23 KPC k platbě [MEDEVIO fa 321799].kpc new file mode 100644 index 0000000..b4c5faf --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [MEDEVIO fa 321799].kpc @@ -0,0 +1,6 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000000249758 230626 +2701907026 000000249758 321799 20100000 AV:MEDEVIO fa 321799 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek 2 faktury].kpc b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek 2 faktury].kpc new file mode 100644 index 0000000..f4dfd34 --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek 2 faktury].kpc @@ -0,0 +1,7 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000002882764 230626 +1387720540 000000046464 91260794 27000000 AV:Poliklinika Prosek fa 91260794 +1387720540 000002836300 10626 27000000 AV:Poliklinika Prosek fa 96260214 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260763 leciva].kpc b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260763 leciva].kpc new file mode 100644 index 0000000..1db6ca4 --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260763 leciva].kpc @@ -0,0 +1,6 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000001616540 230626 +1387720540 000001616540 91260763 27000000 AV:Poliklinika Prosek fa 91260763 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260795 klimatizace].kpc b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260795 klimatizace].kpc new file mode 100644 index 0000000..37a9029 --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [Poliklinika Prosek fa 91260795 klimatizace].kpc @@ -0,0 +1,6 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000000019314 230626 +1387720540 000000019314 91260795 27000000 AV:Poliklinika Prosek fa 91260795 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [Ptáček 3 faktury].kpc b/KPC/output/2026-06-23 KPC k platbě [Ptáček 3 faktury].kpc new file mode 100644 index 0000000..89a10e1 --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [Ptáček 3 faktury].kpc @@ -0,0 +1,8 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000001408138 230626 +220205630 000000363210 202605002 03000000 AV:Ptacek fa 202605002 +220205630 000000121408 202604906 03000000 AV:Ptacek fa 202604906 +220205630 000000923520 202604570 03000000 AV:Ptacek fa 202604570 +3 + +5 + diff --git a/KPC/output/2026-06-23 KPC k platbě [QuickSeal fa 110606255].kpc b/KPC/output/2026-06-23 KPC k platbě [QuickSeal fa 110606255].kpc new file mode 100644 index 0000000..a508320 --- /dev/null +++ b/KPC/output/2026-06-23 KPC k platbě [QuickSeal fa 110606255].kpc @@ -0,0 +1,6 @@ +UHL1230626 0000000000000000000000000000 +1 1501 000000 2010 +2 000000-2800046620 00000000262000 230626 +197638875 000000262000 110606255 03000000 AV:QuickSeal fa 110606255 +3 + +5 +