notebookvb

This commit is contained in:
2026-04-11 11:56:54 +02:00
parent 24635b955d
commit c2d94b2362
10 changed files with 507 additions and 35 deletions
+84 -19
View File
@@ -1,12 +1,14 @@
"""
Nacte odpoved lekoveho zaznamu (XML) a ulozi ji do MySQL.
Schema: zprava / predpis / predpis_slozka / vydej / vydej_slozka
Schema: pacient / zprava / predpis / predpis_slozka / vydej / vydej_slozka / predepisujici / vydavajici
Typy a delky presne dle XSD (Cuer2Schema.xsd + CuerSchema.xsd, verze 202501A)
Spusteni:
Spusteni (jednorazova inicializace + import jednoho XML):
python 06UlozitDoMySQL.py
nebo:
python 06UlozitDoMySQL.py cesta/k/odpoved.xml
Pro hromadne stazeni vsech pacientu pouzij 07StahnoutVsechny.py.
"""
import sys
@@ -47,25 +49,49 @@ def ts(s):
# ── DDL ───────────────────────────────────────────────────────────────────────
DDL_TABULKY = [
# smazat v opacnem poradi kvuli FK
# Pouziva se ve vytvor_schema() (DROP + CREATE) pro ciste spusteni
DDL_DROP = [
"DROP TABLE IF EXISTS predpis_slozka",
"DROP TABLE IF EXISTS vydej_slozka",
"DROP TABLE IF EXISTS vydej",
"DROP TABLE IF EXISTS predpis",
"DROP TABLE IF EXISTS zprava",
"DROP TABLE IF EXISTS pacient",
"DROP TABLE IF EXISTS predepisujici",
"DROP TABLE IF EXISTS vydavajici",
]
DDL_CREATE = [
# ── pacient ───────────────────────────────────────────────────────────────
# Zrcadlo registrovanych pacientu z Medicusu (Firebird).
# idpac = IDPAC z KAR tabulky Medicusu.
# poznamka: posledni chyba API (napr. "neztotozneny pacient"); NULL = OK
"""
CREATE TABLE IF NOT EXISTS pacient (
id INT AUTO_INCREMENT PRIMARY KEY,
idpac INT NOT NULL UNIQUE,
prijmeni VARCHAR(35) NOT NULL,
jmena VARCHAR(24),
datum_narozeni DATE NOT NULL,
aktivni TINYINT(1) NOT NULL DEFAULT 1,
poznamka VARCHAR(500),
INDEX idx_prijmeni (prijmeni)
) ENGINE=InnoDB
""",
# ── zprava ────────────────────────────────────────────────────────────────
# zprava_odpoved_type + zprava_type:
# ID_Zpravy CHAR(36), Verze, Odeslano dateTime
# Aplikace(512), ID_Podani CHAR(36), Prijato dateTime
# jmeno_osoby_type: Prijmeni(35), Jmena(24)
# pacient_id: FK na pacient.id (NULL pokud volano z 06 primo)
# xml_soubor: relativni cesta k ulozene XML odpovedi
"""
CREATE TABLE zprava (
CREATE TABLE IF NOT EXISTS zprava (
id INT AUTO_INCREMENT PRIMARY KEY,
id_zpravy CHAR(36) NOT NULL UNIQUE,
pacient_id INT,
verze VARCHAR(20),
odeslano DATETIME,
aplikace VARCHAR(512),
@@ -74,7 +100,10 @@ DDL_TABULKY = [
pacient_prijmeni VARCHAR(35),
pacient_jmena VARCHAR(24),
pacient_datum_narozeni DATE,
xml_soubor VARCHAR(255),
stazeno DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (pacient_id) REFERENCES pacient(id) ON DELETE SET NULL,
INDEX idx_pacient_id (pacient_id),
INDEX idx_pacient (pacient_prijmeni, pacient_datum_narozeni)
) ENGINE=InnoDB
""",
@@ -90,7 +119,7 @@ DDL_TABULKY = [
# inn_predpis_type: Nazev(200) — nejdelsi nazev mezi typy
# iplp_predpis_type: PostupPripravy(4000), Nazev(146), CestaPodani(15), Forma(27)
"""
CREATE TABLE predpis (
CREATE TABLE IF NOT EXISTS predpis (
id INT AUTO_INCREMENT PRIMARY KEY,
zprava_id INT NOT NULL,
id_lp_predpis CHAR(36) NOT NULL UNIQUE,
@@ -120,7 +149,7 @@ DDL_TABULKY = [
# Mnozstvi DECIMAL(15,6) NOT NULL, Jednotka ENUM('g','ks') NOT NULL,
# Nazev(200) NOT NULL, Surovina CHAR(7)?, HVLPReg CHAR(7)?
"""
CREATE TABLE predpis_slozka (
CREATE TABLE IF NOT EXISTS predpis_slozka (
id INT AUTO_INCREMENT PRIMARY KEY,
predpis_id INT NOT NULL,
mnozstvi DECIMAL(15,6) NOT NULL,
@@ -140,7 +169,7 @@ DDL_TABULKY = [
# lek — vzdy jen jeden z: HVLPReg / HVLPNereg / IPLP
# iplp_type (vydej): KodVZP CHAR(7)?, PostupPripravy(4000), Nazev(146), CestaPodani(15)
"""
CREATE TABLE vydej (
CREATE TABLE IF NOT EXISTS vydej (
id INT AUTO_INCREMENT PRIMARY KEY,
zprava_id INT NOT NULL,
id_lp_vydej CHAR(36) NOT NULL UNIQUE,
@@ -175,7 +204,7 @@ DDL_TABULKY = [
# Nazev(200) NOT NULL, HrazenoZP DECIMAL(9,2)?,
# Surovina CHAR(7)?, HVLPReg CHAR(7)?
"""
CREATE TABLE vydej_slozka (
CREATE TABLE IF NOT EXISTS vydej_slozka (
id INT AUTO_INCREMENT PRIMARY KEY,
vydej_id INT NOT NULL,
mnozstvi DECIMAL(15,6) NOT NULL,
@@ -197,7 +226,7 @@ DDL_TABULKY = [
# Telefon(20)?
# lekar_kod = predpis.kod_predepisujiciho
"""
CREATE TABLE predepisujici (
CREATE TABLE IF NOT EXISTS predepisujici (
id INT AUTO_INCREMENT PRIMARY KEY,
lekar_kod CHAR(36) NOT NULL UNIQUE,
prijmeni VARCHAR(35),
@@ -220,7 +249,7 @@ DDL_TABULKY = [
# PZS: Nazev(200), Telefon(20)?, Adresa: NazevUlice, CisloPopisne, CisloOrientacni, NazevObce, PSC
# lekarnik_kod = vydej.kod_vydavajiciho
"""
CREATE TABLE vydavajici (
CREATE TABLE IF NOT EXISTS vydavajici (
id INT AUTO_INCREMENT PRIMARY KEY,
lekarnik_kod CHAR(36) NOT NULL UNIQUE,
prijmeni VARCHAR(35),
@@ -236,13 +265,38 @@ DDL_TABULKY = [
def vytvor_schema(conn):
"""DROP + CREATE vsech tabulek. Pouzij pro ciste spusteni / reset dat."""
with conn.cursor() as cur:
for stmt in DDL_TABULKY:
for stmt in DDL_DROP:
cur.execute(stmt)
for stmt in DDL_CREATE:
stmt = stmt.strip()
if stmt:
cur.execute(stmt)
conn.commit()
print("Schema OK (5 tabulek smazano a vytvoreno znovu)")
print("Schema OK tabulky smazany a vytvoreny znovu")
def inicializuj_schema(conn):
"""CREATE TABLE IF NOT EXISTS — bezpecne pro opakowane spusteni (neznici data)."""
with conn.cursor() as cur:
for stmt in DDL_CREATE:
stmt = stmt.strip()
if stmt:
cur.execute(stmt)
# Zpetna kompatibilita: pridat sloupec poznamka pokud jeste neexistuje
cur.execute("""
SELECT COUNT(*) AS cnt
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'pacient'
AND COLUMN_NAME = 'poznamka'
""")
if cur.fetchone()["cnt"] == 0:
cur.execute(
"ALTER TABLE pacient ADD COLUMN poznamka VARCHAR(500) NULL DEFAULT NULL"
)
conn.commit()
# ── parsovani predepisujicich a vydavajicich ─────────────────────────────────
@@ -519,25 +573,36 @@ def _najdi_id(cur, tabulka, sloupec, hodnota):
return row["id"] if row else None
def uloz(conn, zprava, predpisy, vydeji, predepisujici, vydavajici):
def uloz(conn, zprava, predpisy, vydeji, predepisujici, vydavajici,
pacient_id=None, xml_soubor=None):
"""
Ulozi parsovana data do MySQL.
pacient_id — FK na tabulku pacient (None pokud volano primo z 06)
xml_soubor — relativni cesta k archivnimu XML souboru (None pokud neni archivovano)
"""
iplp_predpisu = 0
iplp_vydejuu = 0
with conn.cursor() as cur:
# ── zprava ────────────────────────────────────────────────────────────
zprava_row = dict(zprava)
zprava_row["pacient_id"] = pacient_id
zprava_row["xml_soubor"] = xml_soubor
cur.execute("""
INSERT INTO zprava
(id_zpravy, verze, odeslano, aplikace, id_podani, prijato,
pacient_prijmeni, pacient_jmena, pacient_datum_narozeni)
(id_zpravy, pacient_id, verze, odeslano, aplikace, id_podani, prijato,
pacient_prijmeni, pacient_jmena, pacient_datum_narozeni, xml_soubor)
VALUES
(%(id_zpravy)s, %(verze)s, %(odeslano)s, %(aplikace)s,
(%(id_zpravy)s, %(pacient_id)s, %(verze)s, %(odeslano)s, %(aplikace)s,
%(id_podani)s, %(prijato)s,
%(pacient_prijmeni)s, %(pacient_jmena)s, %(pacient_datum_narozeni)s)
%(pacient_prijmeni)s, %(pacient_jmena)s, %(pacient_datum_narozeni)s,
%(xml_soubor)s)
ON DUPLICATE KEY UPDATE
prijato = VALUES(prijato),
xml_soubor = COALESCE(VALUES(xml_soubor), xml_soubor),
stazeno = CURRENT_TIMESTAMP
""", zprava)
""", zprava_row)
zprava_id = _najdi_id(cur, "zprava", "id_zpravy", zprava["id_zpravy"])
print(f" zprava id={zprava_id} ({zprava['id_zpravy']})")
@@ -0,0 +1,420 @@
"""
Hromadne stazeni lekovych zaznamu z eReceptu pro registrovane pacienty Medicusu.
Spusteni:
# pouze rodina (testovaci run)
python 07StahnoutVsechny.py --prijmeni Buzalka,Buzalkova,Kusinova
# vsichni registrovani pacienti
python 07StahnoutVsechny.py
Logika poctu mesicu:
- prvni stazeni pacienta → 60 mesicu (maximum)
- opakowane stazeni → ceil(pocet_dni_od_posledniho / 30) + 1
(prekryv 1 mesic pro jistotu, INSERT IGNORE zajisti bez duplikatu)
XML archiv:
xml_archive/YYYY-MM-DD/{Prijmeni}_{Jmena}_{datnar}.xml
Cesta ulozena take v zprava.xml_soubor pro snadne dohledani.
"""
import argparse
import importlib.util
import math
import sys
import time
import uuid
# Windows konzole — nahrad neunikatni znaky misto padu
if hasattr(sys.stdout, "reconfigure"):
sys.stdout.reconfigure(errors="replace")
from datetime import datetime, timezone, date
from pathlib import Path
from xml.sax.saxutils import escape as xml_escape
import fdb
import pymysql
import pymysql.cursors
from requests import Session
from requests_pkcs12 import Pkcs12Adapter
# ── Import parsovaci logiky z 06 ──────────────────────────────────────────────
_spec = importlib.util.spec_from_file_location(
"m06", Path(__file__).parent / "06UlozitDoMySQL.py"
)
_m06 = importlib.util.module_from_spec(_spec)
_spec.loader.exec_module(_m06)
parsuj_xml = _m06.parsuj_xml
uloz = _m06.uloz
inicializuj_schema = _m06.inicializuj_schema
# ── Konfigurace eRecept ───────────────────────────────────────────────────────
PFX_FILE = r"C:\Users\vlado\PycharmProjects\Recepty\AMBSUKL214235369G_31DEC2024.pfx"
PFX_PASS = "Vlado7309208104++"
API_USER = "e08c89c6-2b1a-4eba-8ed9-4e3e63618379"
API_PASS = "Buzalka@Vladimir2025"
UZIVATEL = "E08C89C6-2B1A-4EBA-8ED9-4E3E63618379"
PRACOVISTE = "00214235367"
ENDPOINT = "https://lekar-soap.erecept.sukl.cz/cuer/Lekar2"
POCET_ZNAKU_ATC = 7
POCET_MESICU_MAX = 60
PAUZA_MEZI_VOLANIMI = 15 # sekund
# ── Konfigurace Firebird ──────────────────────────────────────────────────────
FB_DSN = r'localhost:c:\medicus 3\data\medicus.fdb'
FB_USER = 'SYSDBA'
FB_PASS = 'masterkey'
FB_CHARSET = 'win1250'
ICP = '09305001'
ODB = '001'
# ── Konfigurace MySQL ─────────────────────────────────────────────────────────
DB = dict(
host = "192.168.1.76",
user = "root",
password = "Vlado9674+",
database = "medicus",
charset = "utf8mb4",
cursorclass = pymysql.cursors.DictCursor,
)
# ── XML archiv ────────────────────────────────────────────────────────────────
XML_DIR = Path(__file__).parent / "xml_archive"
# ── Firebird: nacteni registrovanych pacientu ─────────────────────────────────
_SQL_VSICHNI = """
SELECT
KAR.IDPAC,
KAR.PRIJMENI,
KAR.JMENO,
KAR.DATNAR
FROM KAR
WHERE (vyrazen = 'N')
AND EXISTS (
SELECT id FROM registr r
JOIN icp i ON r.idicp = i.idicp
WHERE r.idpac = kar.idpac
AND (r.datum <= ?)
AND (r.datum_zruseni IS NULL OR r.datum_zruseni >= ?)
AND (r.priznak IN ('V','D','A'))
AND (i.icp = ?)
AND (i.odb = ?)
)
ORDER BY KAR.PRIJMENI_UP, KAR.RODCIS
"""
_SQL_FILTR = """
SELECT
KAR.IDPAC,
KAR.PRIJMENI,
KAR.JMENO,
KAR.DATNAR
FROM KAR
WHERE (vyrazen = 'N')
AND KAR.PRIJMENI IN ({ph})
ORDER BY KAR.PRIJMENI_UP, KAR.RODCIS
"""
def nacti_pacienty(prijmeni_filtr=None):
"""
Vraci seznam dict {idpac, prijmeni, jmeno, datnar}.
prijmeni_filtr: list prijmeni (napr. ['Buzalka', 'Buzalkova']) nebo None = vsichni.
"""
conn = fdb.connect(dsn=FB_DSN, user=FB_USER, password=FB_PASS, charset=FB_CHARSET)
try:
cur = conn.cursor()
if prijmeni_filtr:
ph = ",".join("?" * len(prijmeni_filtr))
cur.execute(_SQL_FILTR.format(ph=ph), prijmeni_filtr)
else:
dnes = date.today().isoformat()
cur.execute(_SQL_VSICHNI, (dnes, dnes, ICP, ODB))
cols = [d[0].lower() for d in cur.description]
return [dict(zip(cols, row)) for row in cur.fetchall()]
finally:
conn.close()
# ── MySQL: pacient UPSERT ─────────────────────────────────────────────────────
def upsert_pacient(cur, pac):
"""
Vlozi nebo aktualizuje pacienta v tabulce pacient.
Vraci MySQL id radku.
"""
cur.execute("""
INSERT INTO pacient (idpac, prijmeni, jmena, datum_narozeni)
VALUES (%s, %s, %s, %s)
ON DUPLICATE KEY UPDATE
prijmeni = VALUES(prijmeni),
jmena = VALUES(jmena)
""", (pac["idpac"], pac["prijmeni"], pac["jmeno"], pac["datnar"]))
cur.execute("SELECT id FROM pacient WHERE idpac = %s", (pac["idpac"],))
return cur.fetchone()["id"]
def posledni_stazeni(cur, pacient_id):
"""Vraci datetime posledniho stazeni, nebo None pro noveho pacienta."""
cur.execute(
"SELECT MAX(stazeno) AS posledni FROM zprava WHERE pacient_id = %s",
(pacient_id,)
)
row = cur.fetchone()
return row["posledni"] if row and row["posledni"] else None
def vypocti_pocet_mesicu(posledni):
"""60 pro prvni stazeni, jinak delta v mesicich + 1 (prekryv)."""
if posledni is None:
return POCET_MESICU_MAX
delta_dni = (datetime.now() - posledni).days
return min(math.ceil(delta_dni / 30) + 1, POCET_MESICU_MAX)
# ── SOAP volani ───────────────────────────────────────────────────────────────
def extrahuj_soap_fault(xml_text):
"""
Pokud XML obsahuje SOAP Fault, vraci text chyby (str).
Pokud je odpoved v poradku, vraci None.
"""
try:
import xml.etree.ElementTree as ET
NS_SOAP = "http://schemas.xmlsoap.org/soap/envelope/"
NS_SUKL = "http://www.sukl.cz/erp/201912"
root = ET.fromstring(xml_text)
body = root.find(f"{{{NS_SOAP}}}Body")
if body is None:
return "Chybejici SOAP Body"
# Zkontroluj SOAP Fault
fault = body.find(f"{{{NS_SOAP}}}Fault")
if fault is None:
fault = body.find("Fault") # nektery server posila bez namespace
if fault is not None:
faultstring = fault.findtext("faultstring") or fault.findtext("faultcode") or "Nezname SOAP Fault"
detail = fault.find("detail")
if detail is not None and detail.text:
faultstring = f"{faultstring}: {detail.text.strip()[:200]}"
return faultstring
# Zkontroluj, ze odpoved je spravneho typu (NacistLekovyZaznamOdpoved)
odpoved = body.find(f"{{{NS_SUKL}}}NacistLekovyZaznamOdpoved")
if odpoved is None:
# Neznamy format — vrat prvni tag jako info
first = list(body)
tag = first[0].tag if first else "prazdne Body"
return f"Neocekavana odpoved: {tag}"
return None # vse OK
except Exception as e:
return f"Chyba pri parsovani odpovedi: {e}"
def uloz_poznamku(conn, pacient_id, poznamka):
"""Ulozi nebo vymaze poznamku (chybu) u pacienta."""
with conn.cursor() as cur:
cur.execute(
"UPDATE pacient SET poznamka = %s WHERE id = %s",
(poznamka, pacient_id)
)
conn.commit()
def nacti_lekovy_zaznam(sess, prijmeni, jmena, datum_narozeni, pocet_mesicu):
"""
Zavola NacistLekovyZaznam pro jednoho pacienta.
Vraci xml_text (str). Vyhazuje RuntimeError pri HTTP chybe.
"""
id_zpravy = str(uuid.uuid4())
odeslano = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S+00:00")
soap = (
'<?xml version="1.0" encoding="UTF-8"?>'
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">'
'<soapenv:Body>'
f'<NacistLekovyZaznamLekarDotaz xmlns="http://www.sukl.cz/erp/201912">'
f'<Doklad>'
f'<Pristupujici>'
f'<Uzivatel>{UZIVATEL}</Uzivatel>'
f'<Pracoviste>{PRACOVISTE}</Pracoviste>'
f'</Pristupujici>'
f'<PocetZnakuATC>{POCET_ZNAKU_ATC}</PocetZnakuATC>'
f'<PocetMesicu>{pocet_mesicu}</PocetMesicu>'
f'<Pacient><Totoznost><Jmeno>'
f'<Prijmeni>{xml_escape(prijmeni)}</Prijmeni>'
f'<Jmena>{xml_escape(jmena)}</Jmena>'
f'</Jmeno><DatumNarozeni>{datum_narozeni}</DatumNarozeni>'
f'</Totoznost></Pacient>'
f'</Doklad>'
f'<Zprava>'
f'<ID_Zpravy>{id_zpravy}</ID_Zpravy>'
f'<Verze>202501A</Verze>'
f'<Odeslano>{odeslano}</Odeslano>'
f'<SW_Klienta>MEDICUS_____</SW_Klienta>'
f'</Zprava>'
f'</NacistLekovyZaznamLekarDotaz>'
'</soapenv:Body>'
'</soapenv:Envelope>'
)
headers = {
"Content-Type": 'text/xml; charset="UTF-8"',
"SOAPAction": '"NacistLekovyZaznam"',
"User-Agent": "Medicus",
}
resp = sess.post(ENDPOINT, data=soap.encode("utf-8"), headers=headers, timeout=60)
if resp.status_code != 200:
raise RuntimeError(f"HTTP {resp.status_code}: {resp.text[:300]}")
return resp.text
# ── XML archiv ────────────────────────────────────────────────────────────────
def uloz_xml_na_disk(xml_text, prijmeni, jmena, datnar_str, dnes_str):
"""
Ulozi XML do xml_archive/YYYY-MM-DD/{Prijmeni}_{Jmena}_{datnar}.xml
Vraci relativni cestu (str) vuci adresari skriptu.
"""
adr = XML_DIR / dnes_str
adr.mkdir(parents=True, exist_ok=True)
nazev = f"{prijmeni}_{jmena}_{datnar_str}.xml".replace(" ", "_")
soubor = adr / nazev
soubor.write_text(xml_text, encoding="utf-8")
return str(soubor.relative_to(Path(__file__).parent))
# ── Hlavni smycka ─────────────────────────────────────────────────────────────
def main():
ap = argparse.ArgumentParser(
description="Hromadne stazeni lekovych zaznamu z eReceptu"
)
ap.add_argument(
"--prijmeni",
help="Filtr prijmeni oddelena carkou, napr: Buzalka,Buzalkova,Kusinova",
default=None,
)
ap.add_argument(
"--limit",
type=int,
default=None,
help="Zpracuj pouze N pacientu",
)
ap.add_argument(
"--offset",
type=int,
default=0,
help="Preskoc prvnich N pacientu (pro postupne davkovani)",
)
args = ap.parse_args()
prijmeni_filtr = None
if args.prijmeni:
prijmeni_filtr = [p.strip() for p in args.prijmeni.split(",")]
print(f"Filtr prijmeni: {prijmeni_filtr}")
# 1. Nacti pacienty z Medicusu
print("Nacitam pacienty z Medicusu (Firebird)...")
pacienti = nacti_pacienty(prijmeni_filtr)
print(f" Nalezeno: {len(pacienti)} pacientu")
if args.offset:
pacienti = pacienti[args.offset:]
print(f" Preskoceno: {args.offset} (--offset {args.offset})")
if args.limit:
pacienti = pacienti[:args.limit]
print(f" Omezeno na: {len(pacienti)} (--limit {args.limit})")
if not pacienti:
print("Zadni pacienti — konec.")
return
# 2. Pripoj se k MySQL, over schema (CREATE IF NOT EXISTS)
print("Pripojuji k MySQL...")
conn = pymysql.connect(**DB)
inicializuj_schema(conn)
# 3. Priprav SOAP session (sdilena pro vsechny pacienty)
sess = Session()
sess.mount("https://", Pkcs12Adapter(
pkcs12_filename=PFX_FILE,
pkcs12_password=PFX_PASS,
))
sess.auth = (API_USER, API_PASS)
dnes_str = date.today().isoformat()
ok = 0
chyby = 0
celkem = len(pacienti)
try:
for i, pac in enumerate(pacienti, 1):
prijmeni = pac["prijmeni"]
jmena = pac["jmeno"]
datnar = pac["datnar"]
datnar_str = datnar.isoformat() if hasattr(datnar, "isoformat") else str(datnar)
print(f"\n[{i}/{celkem}] {prijmeni} {jmena} (*{datnar_str})")
# UPSERT pacienta, zjisti kdy byl naposledy stazen
with conn.cursor() as cur:
pacient_id = upsert_pacient(cur, pac)
posledni = posledni_stazeni(cur, pacient_id)
conn.commit()
pocet_mesicu = vypocti_pocet_mesicu(posledni)
print(f" Stahuju {pocet_mesicu} mesicu "
f"(posledni stazeni: {posledni.strftime('%Y-%m-%d') if posledni else 'nikdy'})")
# Zavolej API
try:
xml_text = nacti_lekovy_zaznam(sess, prijmeni, jmena, datnar_str, pocet_mesicu)
except Exception as e:
zprava_chyby = str(e)[:400]
print(f" CHYBA API: {zprava_chyby}")
uloz_poznamku(conn, pacient_id, zprava_chyby)
chyby += 1
continue
# Detekuj SOAP Fault v odpovedi (HTTP 200 ale chyba uvnitr)
soap_fault = extrahuj_soap_fault(xml_text)
if soap_fault:
print(f" SOAP FAULT: {soap_fault}")
uloz_poznamku(conn, pacient_id, soap_fault[:400])
chyby += 1
continue
# Uloz XML na disk
xml_soubor = uloz_xml_na_disk(xml_text, prijmeni, jmena, datnar_str, dnes_str)
xml_path = Path(__file__).parent / xml_soubor
print(f" XML: {xml_soubor} ({xml_path.stat().st_size // 1024} KB)")
# Parsuj + uloz do MySQL
try:
zprava_d, predpisy, vydeji, predepisujici, vydavajici = parsuj_xml(xml_path)
uloz(conn, zprava_d, predpisy, vydeji, predepisujici, vydavajici,
pacient_id=pacient_id, xml_soubor=xml_soubor)
uloz_poznamku(conn, pacient_id, None) # vymaz predchozi chybu
ok += 1
except Exception as e:
zprava_chyby = str(e)[:400]
print(f" CHYBA parsovani/ulozeni: {zprava_chyby}")
uloz_poznamku(conn, pacient_id, zprava_chyby)
chyby += 1
# Pauza mezi volanimi API (neplati po poslednim pacientovi)
if i < celkem:
print(f" Cekam {PAUZA_MEZI_VOLANIMI}s ...")
time.sleep(PAUZA_MEZI_VOLANIMI)
finally:
conn.close()
sess.close()
print(f"\n{'=' * 55}")
print(f"Hotovo: {ok} OK | {chyby} chyb | celkem {celkem} pacientu")
if __name__ == "__main__":
main()
File diff suppressed because one or more lines are too long