notebookvb
This commit is contained in:
@@ -0,0 +1,523 @@
|
|||||||
|
"""
|
||||||
|
Nacte odpoved lekoveho zaznamu (XML) a ulozi ji do MySQL.
|
||||||
|
Schema: zprava / predpis / predpis_slozka / vydej / vydej_slozka
|
||||||
|
Typy a delky presne dle XSD (Cuer2Schema.xsd + CuerSchema.xsd, verze 202501A)
|
||||||
|
|
||||||
|
Spusteni:
|
||||||
|
python 06UlozitDoMySQL.py
|
||||||
|
nebo:
|
||||||
|
python 06UlozitDoMySQL.py cesta/k/odpoved.xml
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
import pymysql
|
||||||
|
import pymysql.cursors
|
||||||
|
|
||||||
|
# ── konfigurace ───────────────────────────────────────────────────────────────
|
||||||
|
XML_SOUBOR = Path(__file__).parent / "odpoved_lekovy_zaznam.xml"
|
||||||
|
|
||||||
|
DB = dict(
|
||||||
|
host = "192.168.1.76",
|
||||||
|
user = "root",
|
||||||
|
password = "Vlado9674+",
|
||||||
|
database = "medicus",
|
||||||
|
charset = "utf8mb4",
|
||||||
|
cursorclass = pymysql.cursors.DictCursor,
|
||||||
|
)
|
||||||
|
|
||||||
|
NS = "http://www.sukl.cz/erp/201912"
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
def t(el, tag):
|
||||||
|
"""Prvni potomek s danym tagem → text nebo None."""
|
||||||
|
found = el.find(f"{{{NS}}}{tag}")
|
||||||
|
return found.text.strip() if found is not None and found.text else None
|
||||||
|
|
||||||
|
|
||||||
|
def datum(s):
|
||||||
|
return s[:10] if s else None
|
||||||
|
|
||||||
|
|
||||||
|
def ts(s):
|
||||||
|
return s[:19].replace("T", " ") if s else None
|
||||||
|
|
||||||
|
|
||||||
|
# ── DDL ───────────────────────────────────────────────────────────────────────
|
||||||
|
DDL_TABULKY = [
|
||||||
|
# smazat v opacnem poradi kvuli FK
|
||||||
|
"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",
|
||||||
|
|
||||||
|
# ── 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)
|
||||||
|
"""
|
||||||
|
CREATE TABLE zprava (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
id_zpravy CHAR(36) NOT NULL UNIQUE,
|
||||||
|
verze VARCHAR(20),
|
||||||
|
odeslano DATETIME,
|
||||||
|
aplikace VARCHAR(512),
|
||||||
|
id_podani CHAR(36),
|
||||||
|
prijato DATETIME,
|
||||||
|
pacient_prijmeni VARCHAR(35),
|
||||||
|
pacient_jmena VARCHAR(24),
|
||||||
|
pacient_datum_narozeni DATE,
|
||||||
|
stazeno DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
INDEX idx_pacient (pacient_prijmeni, pacient_datum_narozeni)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
|
||||||
|
# ── predpis ───────────────────────────────────────────────────────────────
|
||||||
|
# lz_nacteni_predepsany_lp_erp_type:
|
||||||
|
# ID_LP_Predpis CHAR(36) NOT NULL, KodPredepisujiciho(36) NOT NULL,
|
||||||
|
# DatumVystaveni date NOT NULL, Mnozstvi int(1-9999) NOT NULL,
|
||||||
|
# Navod(80) NOT NULL, Opakovani int?, ModryPruh boolean?
|
||||||
|
# lek — vzdy jen jeden z: HVLPReg / HVLPNereg / IPLP / INN
|
||||||
|
# hvlp_type: Kod CHAR(7)?, ATC(7)?, Nazev(146)!, Forma(27)?,
|
||||||
|
# Sila(24)?, CestaPodani(15)?, Baleni VARCHAR(22)?
|
||||||
|
# inn_predpis_type: Nazev(200) — nejdelsi nazev mezi typy
|
||||||
|
# iplp_predpis_type: PostupPripravy(4000), Nazev(146), CestaPodani(15), Forma(27)
|
||||||
|
"""
|
||||||
|
CREATE TABLE predpis (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
zprava_id INT NOT NULL,
|
||||||
|
id_lp_predpis CHAR(36) NOT NULL UNIQUE,
|
||||||
|
kod_predepisujiciho VARCHAR(36) NOT NULL,
|
||||||
|
datum_vystaveni DATE NOT NULL,
|
||||||
|
mnozstvi SMALLINT NOT NULL,
|
||||||
|
navod VARCHAR(80) NOT NULL,
|
||||||
|
opakovani INT,
|
||||||
|
modry_pruh TINYINT(1),
|
||||||
|
typ_leku ENUM('HVLPReg','HVLPNereg','IPLP','INN'),
|
||||||
|
lek_kod CHAR(7),
|
||||||
|
atc VARCHAR(7),
|
||||||
|
nazev VARCHAR(200),
|
||||||
|
forma VARCHAR(27),
|
||||||
|
sila VARCHAR(24),
|
||||||
|
cesta_podani VARCHAR(15),
|
||||||
|
baleni VARCHAR(22),
|
||||||
|
postup_pripravy VARCHAR(4000),
|
||||||
|
FOREIGN KEY (zprava_id) REFERENCES zprava(id) ON DELETE CASCADE,
|
||||||
|
INDEX idx_atc (atc),
|
||||||
|
INDEX idx_datum (datum_vystaveni)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
|
||||||
|
# ── predpis_slozka ────────────────────────────────────────────────────────
|
||||||
|
# slozka_iplp_predpis_type:
|
||||||
|
# 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 (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
predpis_id INT NOT NULL,
|
||||||
|
mnozstvi DECIMAL(15,6) NOT NULL,
|
||||||
|
jednotka ENUM('g','ks') NOT NULL,
|
||||||
|
nazev VARCHAR(200) NOT NULL,
|
||||||
|
surovina CHAR(7),
|
||||||
|
hvlp_reg CHAR(7),
|
||||||
|
FOREIGN KEY (predpis_id) REFERENCES predpis(id) ON DELETE CASCADE,
|
||||||
|
INDEX idx_nazev (nazev)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
|
||||||
|
# ── vydej ─────────────────────────────────────────────────────────────────
|
||||||
|
# lz_nacteni_vydany_lp_erp_type:
|
||||||
|
# Mnozstvi DECIMAL(6,2) NOT NULL, Navod(80) NOT NULL,
|
||||||
|
# Sarze(50) NOT NULL, SerioveCislo(20)?, Pozn(1000)?
|
||||||
|
# lek — vzdy jen jeden z: HVLPReg / HVLPNereg / IPLP
|
||||||
|
# iplp_type (vydej): KodVZP CHAR(7)?, PostupPripravy(4000), Nazev(146), CestaPodani(15)
|
||||||
|
"""
|
||||||
|
CREATE TABLE vydej (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
zprava_id INT NOT NULL,
|
||||||
|
id_lp_vydej CHAR(36) NOT NULL UNIQUE,
|
||||||
|
id_lp_predpis CHAR(36),
|
||||||
|
kod_vydavajiciho VARCHAR(36) NOT NULL,
|
||||||
|
datum_vydeje DATE NOT NULL,
|
||||||
|
mnozstvi DECIMAL(6,2) NOT NULL,
|
||||||
|
navod VARCHAR(80) NOT NULL,
|
||||||
|
exspirace DATE,
|
||||||
|
sarze VARCHAR(50) NOT NULL,
|
||||||
|
seriove_cislo VARCHAR(20),
|
||||||
|
pozn VARCHAR(1000),
|
||||||
|
typ_leku ENUM('HVLPReg','HVLPNereg','IPLP'),
|
||||||
|
lek_kod CHAR(7),
|
||||||
|
atc VARCHAR(7),
|
||||||
|
nazev VARCHAR(146),
|
||||||
|
forma VARCHAR(27),
|
||||||
|
sila VARCHAR(24),
|
||||||
|
cesta_podani VARCHAR(15),
|
||||||
|
postup_pripravy VARCHAR(4000),
|
||||||
|
FOREIGN KEY (zprava_id) REFERENCES zprava(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (id_lp_predpis) REFERENCES predpis(id_lp_predpis) ON DELETE SET NULL,
|
||||||
|
INDEX idx_predpis (id_lp_predpis),
|
||||||
|
INDEX idx_atc (atc),
|
||||||
|
INDEX idx_datum (datum_vydeje)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
|
||||||
|
# ── vydej_slozka ──────────────────────────────────────────────────────────
|
||||||
|
# slozka_iplp_type:
|
||||||
|
# Mnozstvi DECIMAL(15,6) NOT NULL, Jednotka ENUM('g','ks') NOT NULL,
|
||||||
|
# Nazev(200) NOT NULL, HrazenoZP DECIMAL(9,2)?,
|
||||||
|
# Surovina CHAR(7)?, HVLPReg CHAR(7)?
|
||||||
|
"""
|
||||||
|
CREATE TABLE vydej_slozka (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
vydej_id INT NOT NULL,
|
||||||
|
mnozstvi DECIMAL(15,6) NOT NULL,
|
||||||
|
jednotka ENUM('g','ks') NOT NULL,
|
||||||
|
nazev VARCHAR(200) NOT NULL,
|
||||||
|
hrazeno_zp DECIMAL(9,2),
|
||||||
|
surovina CHAR(7),
|
||||||
|
hvlp_reg CHAR(7),
|
||||||
|
FOREIGN KEY (vydej_id) REFERENCES vydej(id) ON DELETE CASCADE,
|
||||||
|
INDEX idx_nazev (nazev)
|
||||||
|
) ENGINE=InnoDB
|
||||||
|
""",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def vytvor_schema(conn):
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
for stmt in DDL_TABULKY:
|
||||||
|
stmt = stmt.strip()
|
||||||
|
if stmt:
|
||||||
|
cur.execute(stmt)
|
||||||
|
conn.commit()
|
||||||
|
print("Schema OK (5 tabulek smazano a vytvoreno znovu)")
|
||||||
|
|
||||||
|
|
||||||
|
# ── parsovani leku ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def parsuj_slozky_predpis(lek_el):
|
||||||
|
"""Ze IPLP elementu vraci seznam slovniku pro predpis_slozka."""
|
||||||
|
slozky = []
|
||||||
|
for s in lek_el.findall(f"{{{NS}}}Slozka"):
|
||||||
|
slozky.append(dict(
|
||||||
|
mnozstvi = t(s, "Mnozstvi"),
|
||||||
|
jednotka = t(s, "Jednotka"),
|
||||||
|
nazev = t(s, "Nazev"),
|
||||||
|
surovina = t(s, "Surovina"),
|
||||||
|
hvlp_reg = t(s, "HVLPReg"),
|
||||||
|
))
|
||||||
|
return slozky
|
||||||
|
|
||||||
|
|
||||||
|
def parsuj_slozky_vydej(lek_el):
|
||||||
|
"""Ze IPLP elementu vraci seznam slovniku pro vydej_slozka."""
|
||||||
|
slozky = []
|
||||||
|
for s in lek_el.findall(f"{{{NS}}}Slozka"):
|
||||||
|
slozky.append(dict(
|
||||||
|
mnozstvi = t(s, "Mnozstvi"),
|
||||||
|
jednotka = t(s, "Jednotka"),
|
||||||
|
nazev = t(s, "Nazev"),
|
||||||
|
hrazeno_zp = t(s, "HrazenoZP"),
|
||||||
|
surovina = t(s, "Surovina"),
|
||||||
|
hvlp_reg = t(s, "HVLPReg"),
|
||||||
|
))
|
||||||
|
return slozky
|
||||||
|
|
||||||
|
|
||||||
|
def parsuj_lek_predpis(p):
|
||||||
|
"""Vraci (lek_fields dict, slozky list).
|
||||||
|
Typ leku: HVLPReg / HVLPNereg / IPLP / INN — vzdy jen jeden.
|
||||||
|
"""
|
||||||
|
for typ in ("HVLPReg", "HVLPNereg"):
|
||||||
|
lek = p.find(f"{{{NS}}}{typ}")
|
||||||
|
if lek is not None:
|
||||||
|
return dict(
|
||||||
|
typ_leku = typ,
|
||||||
|
lek_kod = t(lek, "Kod"),
|
||||||
|
atc = t(lek, "ATC"),
|
||||||
|
nazev = t(lek, "Nazev"),
|
||||||
|
forma = t(lek, "Forma"),
|
||||||
|
sila = t(lek, "Sila"),
|
||||||
|
cesta_podani = t(lek, "CestaPodani"),
|
||||||
|
baleni = t(lek, "Baleni"),
|
||||||
|
postup_pripravy = None,
|
||||||
|
), []
|
||||||
|
|
||||||
|
lek = p.find(f"{{{NS}}}IPLP")
|
||||||
|
if lek is not None:
|
||||||
|
return dict(
|
||||||
|
typ_leku = "IPLP",
|
||||||
|
lek_kod = None,
|
||||||
|
atc = None,
|
||||||
|
nazev = t(lek, "Nazev"),
|
||||||
|
forma = t(lek, "Forma"),
|
||||||
|
sila = None,
|
||||||
|
cesta_podani = t(lek, "CestaPodani"),
|
||||||
|
baleni = None,
|
||||||
|
postup_pripravy = t(lek, "PostupPripravy"),
|
||||||
|
), parsuj_slozky_predpis(lek)
|
||||||
|
|
||||||
|
lek = p.find(f"{{{NS}}}INN")
|
||||||
|
if lek is not None:
|
||||||
|
return dict(
|
||||||
|
typ_leku = "INN",
|
||||||
|
lek_kod = None,
|
||||||
|
atc = None,
|
||||||
|
nazev = t(lek, "Nazev"),
|
||||||
|
forma = t(lek, "Forma"),
|
||||||
|
sila = t(lek, "Sila"),
|
||||||
|
cesta_podani = t(lek, "CestaPodani"),
|
||||||
|
baleni = t(lek, "Baleni"),
|
||||||
|
postup_pripravy = None,
|
||||||
|
), []
|
||||||
|
|
||||||
|
return dict(typ_leku=None, lek_kod=None, atc=None, nazev=None,
|
||||||
|
forma=None, sila=None, cesta_podani=None,
|
||||||
|
baleni=None, postup_pripravy=None), []
|
||||||
|
|
||||||
|
|
||||||
|
def parsuj_lek_vydej(v):
|
||||||
|
"""Vraci (lek_fields dict, slozky list).
|
||||||
|
Typ leku: HVLPReg / HVLPNereg / IPLP — vzdy jen jeden.
|
||||||
|
"""
|
||||||
|
for typ in ("HVLPReg", "HVLPNereg"):
|
||||||
|
lek = v.find(f"{{{NS}}}{typ}")
|
||||||
|
if lek is not None:
|
||||||
|
return dict(
|
||||||
|
typ_leku = typ,
|
||||||
|
lek_kod = t(lek, "Kod"),
|
||||||
|
atc = t(lek, "ATC"),
|
||||||
|
nazev = t(lek, "Nazev"),
|
||||||
|
forma = t(lek, "Forma"),
|
||||||
|
sila = t(lek, "Sila"),
|
||||||
|
cesta_podani = t(lek, "CestaPodani"),
|
||||||
|
postup_pripravy = None,
|
||||||
|
), []
|
||||||
|
|
||||||
|
lek = v.find(f"{{{NS}}}IPLP")
|
||||||
|
if lek is not None:
|
||||||
|
return dict(
|
||||||
|
typ_leku = "IPLP",
|
||||||
|
lek_kod = t(lek, "KodVZP"),
|
||||||
|
atc = None,
|
||||||
|
nazev = t(lek, "Nazev"),
|
||||||
|
forma = None,
|
||||||
|
sila = None,
|
||||||
|
cesta_podani = t(lek, "CestaPodani"),
|
||||||
|
postup_pripravy = t(lek, "PostupPripravy"),
|
||||||
|
), parsuj_slozky_vydej(lek)
|
||||||
|
|
||||||
|
return dict(typ_leku=None, lek_kod=None, atc=None, nazev=None,
|
||||||
|
forma=None, sila=None, cesta_podani=None,
|
||||||
|
postup_pripravy=None), []
|
||||||
|
|
||||||
|
|
||||||
|
# ── parsovani XML ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def parsuj_xml(xml_soubor):
|
||||||
|
tree = ET.parse(xml_soubor)
|
||||||
|
root = tree.getroot()
|
||||||
|
odpoved = root[0][0] # Envelope > Body > NacistLekovyZaznamOdpoved
|
||||||
|
|
||||||
|
# Doklad prvni, Zprava druha — presne dle XSD sequence
|
||||||
|
doklad = odpoved.find(f"{{{NS}}}Doklad")
|
||||||
|
zpr = odpoved.find(f"{{{NS}}}Zprava")
|
||||||
|
|
||||||
|
# ── Zprava ───────────────────────────────────────────────────────────────
|
||||||
|
zprava = dict(
|
||||||
|
id_zpravy = t(zpr, "ID_Zpravy"),
|
||||||
|
verze = t(zpr, "Verze"),
|
||||||
|
odeslano = ts(t(zpr, "Odeslano")),
|
||||||
|
aplikace = t(zpr, "Aplikace"),
|
||||||
|
id_podani = t(zpr, "ID_Podani"),
|
||||||
|
prijato = ts(t(zpr, "Prijato")),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ── Pacient ───────────────────────────────────────────────────────────────
|
||||||
|
pac = doklad.find(f"{{{NS}}}Pacient")
|
||||||
|
jmeno = pac.find(f"{{{NS}}}Jmeno")
|
||||||
|
zprava["pacient_prijmeni"] = t(jmeno, "Prijmeni") if jmeno is not None else None
|
||||||
|
zprava["pacient_jmena"] = t(jmeno, "Jmena") if jmeno is not None else None
|
||||||
|
zprava["pacient_datum_narozeni"] = datum(t(pac, "DatumNarozeni"))
|
||||||
|
|
||||||
|
# ── Predpisy ──────────────────────────────────────────────────────────────
|
||||||
|
predpisy = [] # kazda polozka: (row_dict, slozky_list)
|
||||||
|
predpis_seznam = doklad.find(f"{{{NS}}}PredpisSeznam")
|
||||||
|
if predpis_seznam is not None:
|
||||||
|
for p in predpis_seznam.findall(f"{{{NS}}}Predpis"):
|
||||||
|
row = dict(
|
||||||
|
id_lp_predpis = t(p, "ID_LP_Predpis"),
|
||||||
|
kod_predepisujiciho = t(p, "KodPredepisujiciho"),
|
||||||
|
datum_vystaveni = datum(t(p, "DatumVystaveni")),
|
||||||
|
mnozstvi = t(p, "Mnozstvi"),
|
||||||
|
navod = t(p, "Navod"),
|
||||||
|
opakovani = t(p, "Opakovani"),
|
||||||
|
modry_pruh = t(p, "ModryPruh"),
|
||||||
|
)
|
||||||
|
lek_fields, slozky = parsuj_lek_predpis(p)
|
||||||
|
row.update(lek_fields)
|
||||||
|
predpisy.append((row, slozky))
|
||||||
|
|
||||||
|
# ── Vydeji ────────────────────────────────────────────────────────────────
|
||||||
|
vydeji = [] # kazda polozka: (row_dict, slozky_list)
|
||||||
|
vydej_seznam = doklad.find(f"{{{NS}}}VydejSeznam")
|
||||||
|
if vydej_seznam is not None:
|
||||||
|
for v in vydej_seznam.findall(f"{{{NS}}}Vydej"):
|
||||||
|
row = dict(
|
||||||
|
id_lp_vydej = t(v, "ID_LP_Vydej"),
|
||||||
|
id_lp_predpis = t(v, "ID_LP_Predpis"),
|
||||||
|
kod_vydavajiciho = t(v, "KodVydavajiciho"),
|
||||||
|
datum_vydeje = datum(t(v, "DatumVydeje")),
|
||||||
|
mnozstvi = t(v, "Mnozstvi"),
|
||||||
|
navod = t(v, "Navod"),
|
||||||
|
exspirace = datum(t(v, "Exspirace")),
|
||||||
|
sarze = t(v, "Sarze"),
|
||||||
|
seriove_cislo = t(v, "SerioveCislo"),
|
||||||
|
pozn = t(v, "Pozn"),
|
||||||
|
)
|
||||||
|
lek_fields, slozky = parsuj_lek_vydej(v)
|
||||||
|
row.update(lek_fields)
|
||||||
|
vydeji.append((row, slozky))
|
||||||
|
|
||||||
|
return zprava, predpisy, vydeji
|
||||||
|
|
||||||
|
|
||||||
|
# ── ulozeni do DB ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _najdi_id(cur, tabulka, sloupec, hodnota):
|
||||||
|
"""Pomocna funkce — vrati id radku dle unikatniho sloupce."""
|
||||||
|
cur.execute(f"SELECT id FROM {tabulka} WHERE {sloupec} = %s", (hodnota,))
|
||||||
|
row = cur.fetchone()
|
||||||
|
return row["id"] if row else None
|
||||||
|
|
||||||
|
|
||||||
|
def uloz(conn, zprava, predpisy, vydeji):
|
||||||
|
iplp_predpisu = 0
|
||||||
|
iplp_vydejuu = 0
|
||||||
|
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
|
||||||
|
# ── zprava ────────────────────────────────────────────────────────────
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO zprava
|
||||||
|
(id_zpravy, verze, odeslano, aplikace, id_podani, prijato,
|
||||||
|
pacient_prijmeni, pacient_jmena, pacient_datum_narozeni)
|
||||||
|
VALUES
|
||||||
|
(%(id_zpravy)s, %(verze)s, %(odeslano)s, %(aplikace)s,
|
||||||
|
%(id_podani)s, %(prijato)s,
|
||||||
|
%(pacient_prijmeni)s, %(pacient_jmena)s, %(pacient_datum_narozeni)s)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
prijato = VALUES(prijato),
|
||||||
|
stazeno = CURRENT_TIMESTAMP
|
||||||
|
""", zprava)
|
||||||
|
zprava_id = _najdi_id(cur, "zprava", "id_zpravy", zprava["id_zpravy"])
|
||||||
|
print(f" zprava id={zprava_id} ({zprava['id_zpravy']})")
|
||||||
|
|
||||||
|
# ── predpisy + jejich slozky ───────────────────────────────────────────
|
||||||
|
vlozeno_p = 0
|
||||||
|
vlozeno_ps = 0
|
||||||
|
for row, slozky in predpisy:
|
||||||
|
row["zprava_id"] = zprava_id
|
||||||
|
cur.execute("""
|
||||||
|
INSERT IGNORE INTO predpis
|
||||||
|
(zprava_id, id_lp_predpis, kod_predepisujiciho,
|
||||||
|
datum_vystaveni, mnozstvi, navod, opakovani, modry_pruh,
|
||||||
|
typ_leku, lek_kod, atc, nazev, forma, sila,
|
||||||
|
cesta_podani, baleni, postup_pripravy)
|
||||||
|
VALUES
|
||||||
|
(%(zprava_id)s, %(id_lp_predpis)s, %(kod_predepisujiciho)s,
|
||||||
|
%(datum_vystaveni)s, %(mnozstvi)s, %(navod)s,
|
||||||
|
%(opakovani)s, %(modry_pruh)s,
|
||||||
|
%(typ_leku)s, %(lek_kod)s, %(atc)s, %(nazev)s, %(forma)s,
|
||||||
|
%(sila)s, %(cesta_podani)s, %(baleni)s, %(postup_pripravy)s)
|
||||||
|
""", row)
|
||||||
|
vlozeno_p += cur.rowcount
|
||||||
|
|
||||||
|
if slozky:
|
||||||
|
iplp_predpisu += 1
|
||||||
|
predpis_db_id = cur.lastrowid or _najdi_id(cur, "predpis", "id_lp_predpis", row["id_lp_predpis"])
|
||||||
|
for s in slozky:
|
||||||
|
s["predpis_id"] = predpis_db_id
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO predpis_slozka
|
||||||
|
(predpis_id, mnozstvi, jednotka, nazev, surovina, hvlp_reg)
|
||||||
|
VALUES
|
||||||
|
(%(predpis_id)s, %(mnozstvi)s, %(jednotka)s,
|
||||||
|
%(nazev)s, %(surovina)s, %(hvlp_reg)s)
|
||||||
|
""", s)
|
||||||
|
vlozeno_ps += 1
|
||||||
|
|
||||||
|
print(f" predpisy: {vlozeno_p} novych (celkem {len(predpisy)})")
|
||||||
|
print(f" predpis_slozka: {vlozeno_ps} slozek z {iplp_predpisu} IPLP predpisu")
|
||||||
|
|
||||||
|
# ── vydeji + jejich slozky ────────────────────────────────────────────
|
||||||
|
vlozeno_v = 0
|
||||||
|
vlozeno_vs = 0
|
||||||
|
for row, slozky in vydeji:
|
||||||
|
row["zprava_id"] = zprava_id
|
||||||
|
cur.execute("""
|
||||||
|
INSERT IGNORE INTO vydej
|
||||||
|
(zprava_id, id_lp_vydej, id_lp_predpis, kod_vydavajiciho,
|
||||||
|
datum_vydeje, mnozstvi, navod, exspirace, sarze,
|
||||||
|
seriove_cislo, pozn,
|
||||||
|
typ_leku, lek_kod, atc, nazev, forma, sila,
|
||||||
|
cesta_podani, postup_pripravy)
|
||||||
|
VALUES
|
||||||
|
(%(zprava_id)s, %(id_lp_vydej)s, %(id_lp_predpis)s, %(kod_vydavajiciho)s,
|
||||||
|
%(datum_vydeje)s, %(mnozstvi)s, %(navod)s, %(exspirace)s, %(sarze)s,
|
||||||
|
%(seriove_cislo)s, %(pozn)s,
|
||||||
|
%(typ_leku)s, %(lek_kod)s, %(atc)s, %(nazev)s, %(forma)s,
|
||||||
|
%(sila)s, %(cesta_podani)s, %(postup_pripravy)s)
|
||||||
|
""", row)
|
||||||
|
vlozeno_v += cur.rowcount
|
||||||
|
|
||||||
|
if slozky:
|
||||||
|
iplp_vydejuu += 1
|
||||||
|
vydej_db_id = cur.lastrowid or _najdi_id(cur, "vydej", "id_lp_vydej", row["id_lp_vydej"])
|
||||||
|
for s in slozky:
|
||||||
|
s["vydej_id"] = vydej_db_id
|
||||||
|
cur.execute("""
|
||||||
|
INSERT INTO vydej_slozka
|
||||||
|
(vydej_id, mnozstvi, jednotka, nazev,
|
||||||
|
hrazeno_zp, surovina, hvlp_reg)
|
||||||
|
VALUES
|
||||||
|
(%(vydej_id)s, %(mnozstvi)s, %(jednotka)s, %(nazev)s,
|
||||||
|
%(hrazeno_zp)s, %(surovina)s, %(hvlp_reg)s)
|
||||||
|
""", s)
|
||||||
|
vlozeno_vs += 1
|
||||||
|
|
||||||
|
print(f" vydeji: {vlozeno_v} novych (celkem {len(vydeji)})")
|
||||||
|
print(f" vydej_slozka: {vlozeno_vs} slozek z {iplp_vydejuu} IPLP vydejuu")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
# ── main ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def main():
|
||||||
|
xml = Path(sys.argv[1]) if len(sys.argv) > 1 else XML_SOUBOR
|
||||||
|
print(f"XML: {xml} ({xml.stat().st_size // 1024} KB)")
|
||||||
|
|
||||||
|
print("Parsovani XML ...")
|
||||||
|
zprava, predpisy, vydeji = parsuj_xml(xml)
|
||||||
|
print(f" -> {len(predpisy)} predpisu, {len(vydeji)} vydejuu")
|
||||||
|
|
||||||
|
print("Pripojeni k MySQL ...")
|
||||||
|
conn = pymysql.connect(**DB)
|
||||||
|
try:
|
||||||
|
vytvor_schema(conn)
|
||||||
|
print("Ukladani ...")
|
||||||
|
uloz(conn, zprava, predpisy, vydeji)
|
||||||
|
print("Hotovo OK")
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
# Lékový záznam eRecept → MySQL
|
||||||
|
|
||||||
|
Popis pipeline pro stažení lékového záznamu pacienta z eRecept SÚKL API
|
||||||
|
a jeho uložení do relační databáze MySQL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Soubory
|
||||||
|
|
||||||
|
| Soubor | Co dělá |
|
||||||
|
|--------|---------|
|
||||||
|
| `05UlozitOdpoved.py` | Zavolá SOAP API, stáhne XML odpověď, uloží ji do `odpoved_lekovy_zaznam.xml` |
|
||||||
|
| `06UlozitDoMySQL.py` | Naparsuje uložené XML, vytvoří/přepíše tabulky v MySQL, vloží data |
|
||||||
|
|
||||||
|
### Typické spuštění
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. stáhnout čerstvá data z eReceptu
|
||||||
|
python 05UlozitOdpoved.py
|
||||||
|
|
||||||
|
# 2. uložit do databáze
|
||||||
|
python 06UlozitDoMySQL.py
|
||||||
|
|
||||||
|
# nebo předat jiný XML soubor
|
||||||
|
python 06UlozitDoMySQL.py C:\cesta\k\jine_odpovedi.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Autentizace (eRecept SÚKL, ostrý provoz)
|
||||||
|
|
||||||
|
| Parametr | Hodnota |
|
||||||
|
|----------|---------|
|
||||||
|
| Endpoint | `https://lekar-soap.erecept.sukl.cz/cuer/Lekar2` |
|
||||||
|
| mTLS certifikát | `AMBSUKL214235369G_31DEC2024.pfx` (platnost do 31. 12. 2026) |
|
||||||
|
| HTTP Basic user | UUID lékaře `e08c89c6-2b1a-4eba-8ed9-4e3e63618379` |
|
||||||
|
| SOAP operace | `NacistLekovyZaznam` |
|
||||||
|
| XML namespace | `http://www.sukl.cz/erp/201912` |
|
||||||
|
| Verze zprávy | `202501A` |
|
||||||
|
|
||||||
|
Certifikát = identifikace **ordinace**, UUID+heslo = identifikace **lékaře jako osoby**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dotaz — parametry `NacistLekovyZaznamLekarDotaz`
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<Doklad>
|
||||||
|
<Pristupujici>
|
||||||
|
<Uzivatel>UUID lékaře</Uzivatel>
|
||||||
|
<Pracoviste>IČP ordinace</Pracoviste>
|
||||||
|
</Pristupujici>
|
||||||
|
<PocetZnakuATC>7</PocetZnakuATC> <!-- 5 nebo 7 -->
|
||||||
|
<PocetMesicu>60</PocetMesicu> <!-- max 99 -->
|
||||||
|
<Pacient>
|
||||||
|
<Totoznost>
|
||||||
|
<Jmeno><Prijmeni>...</Prijmeni><Jmena>...</Jmena></Jmeno>
|
||||||
|
<DatumNarozeni>YYYY-MM-DD</DatumNarozeni>
|
||||||
|
</Totoznost>
|
||||||
|
</Pacient>
|
||||||
|
</Doklad>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Struktura XML odpovědi
|
||||||
|
|
||||||
|
Dle XSD `Cuer2Schema.xsd` + `CuerSchema.xsd`, verze `202501A`:
|
||||||
|
|
||||||
|
```
|
||||||
|
NacistLekovyZaznamOdpoved
|
||||||
|
├── Doklad
|
||||||
|
│ ├── Pacient – jméno + datum narození
|
||||||
|
│ ├── PredepisujiciSeznam – lékaři, kteří předepisovali
|
||||||
|
│ ├── VydavajiciSeznam – lékárny, kde byl výdej
|
||||||
|
│ ├── PredpisSeznam
|
||||||
|
│ │ └── Predpis × N – co bylo předepsáno
|
||||||
|
│ ├── VydejSeznam
|
||||||
|
│ │ └── Vydej × N – co bylo vydáno v lékárně
|
||||||
|
│ └── DuplicitaSeznam – duplicitní výdeje
|
||||||
|
└── Zprava – metadata odpovědi (ID, čas, verze SW)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typy léků v Predpis i Vydej
|
||||||
|
|
||||||
|
Každý předpis / výdej obsahuje právě **jeden** z těchto elementů:
|
||||||
|
|
||||||
|
| Typ | Popis | Klíčová pole |
|
||||||
|
|-----|-------|-------------|
|
||||||
|
| `HVLPReg` | Registrovaný hromadně vyráběný LP | Kod (SÚKL), ATC, Nazev, Forma, Sila, Baleni |
|
||||||
|
| `HVLPNereg` | Neregistrovaný HVLP | stejná struktura jako HVLPReg |
|
||||||
|
| `IPLP` | Individuálně připravovaný LP (magistraliter) | Nazev, PostupPripravy (receptura), Slozka[] |
|
||||||
|
| `INN` | Předpis účinnou látkou (genericky) | Nazev, Forma, Sila, Baleni |
|
||||||
|
|
||||||
|
#### IPLP — dvojí uložení receptury
|
||||||
|
|
||||||
|
- **Předpis** (`PredpisSeznam/Predpis/IPLP`): lékař zadal recepturu jako **volný text** v `PostupPripravy`. Prvky `Slozka` zde lékař typicky nevyplňuje.
|
||||||
|
- **Výdej** (`VydejSeznam/Vydej/IPLP`): lékárna při přípravě zaznamenala **strukturované složky** (`Slozka` s množstvím, jednotkou a názvem suroviny). Kvalita dat závisí na lékárně — některé rozkládají do detailu (suroviny, obal, taxa laborum), jiné evidují jen 1 ks jako celek.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Databázové schéma — `medicus` (MySQL 9.6)
|
||||||
|
|
||||||
|
Všechny délky a datové typy jsou přesně dle XSD, **ne odhady**.
|
||||||
|
Varianta B — lék je denormalizován přímo do řádku předpisu/výdeje.
|
||||||
|
|
||||||
|
### Relační diagram
|
||||||
|
|
||||||
|
```
|
||||||
|
zprava (1)
|
||||||
|
├── predpis (N)
|
||||||
|
│ └── predpis_slozka (N) -- složky IPLP z předpisu
|
||||||
|
└── vydej (N)
|
||||||
|
└── vydej_slozka (N) -- složky IPLP z výdeje
|
||||||
|
|
||||||
|
vydej.id_lp_predpis → predpis.id_lp_predpis (párování výdeje s předpisem)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tabulka `zprava`
|
||||||
|
|
||||||
|
Jeden řádek = jedna odpověď API (jedno volání `NacistLekovyZaznam`).
|
||||||
|
|
||||||
|
| Sloupec | Typ | Zdroj v XSD |
|
||||||
|
|---------|-----|-------------|
|
||||||
|
| `id_zpravy` | CHAR(36) UNIQUE | `zprava_type.ID_Zpravy` |
|
||||||
|
| `verze` | VARCHAR(20) | `zprava_type.Verze` |
|
||||||
|
| `odeslano` | DATETIME | `zprava_type.Odeslano` |
|
||||||
|
| `aplikace` | VARCHAR(512) | `zprava_odpoved_type.Aplikace` |
|
||||||
|
| `id_podani` | CHAR(36) | `zprava_odpoved_type.ID_Podani` |
|
||||||
|
| `prijato` | DATETIME | `zprava_odpoved_type.Prijato` |
|
||||||
|
| `pacient_prijmeni` | VARCHAR(35) | `jmeno_osoby_type.Prijmeni` |
|
||||||
|
| `pacient_jmena` | VARCHAR(24) | `jmeno_osoby_type.Jmena` |
|
||||||
|
| `pacient_datum_narozeni` | DATE | `lz_totoznost_type.DatumNarozeni` |
|
||||||
|
| `stazeno` | DATETIME | automaticky při INSERT |
|
||||||
|
|
||||||
|
### Tabulka `predpis`
|
||||||
|
|
||||||
|
Dle `lz_nacteni_predepsany_lp_erp_type`.
|
||||||
|
|
||||||
|
| Sloupec | Typ | NOT NULL | Poznámka |
|
||||||
|
|---------|-----|----------|----------|
|
||||||
|
| `id_lp_predpis` | CHAR(36) | ✓ | UUID z eReceptu, globálně unikátní |
|
||||||
|
| `kod_predepisujiciho` | VARCHAR(36) | ✓ | UUID lékaře |
|
||||||
|
| `datum_vystaveni` | DATE | ✓ | |
|
||||||
|
| `mnozstvi` | SMALLINT | ✓ | 1–9999 |
|
||||||
|
| `navod` | VARCHAR(80) | ✓ | max 80 znaků dle XSD |
|
||||||
|
| `opakovani` | INT | | opakování předpisu |
|
||||||
|
| `modry_pruh` | TINYINT(1) | | modrý pruh (návykové látky) |
|
||||||
|
| `typ_leku` | ENUM | | HVLPReg / HVLPNereg / IPLP / INN |
|
||||||
|
| `lek_kod` | CHAR(7) | | kód SÚKL (jen HVLP) |
|
||||||
|
| `atc` | VARCHAR(7) | | ATC kód (jen HVLP) |
|
||||||
|
| `nazev` | VARCHAR(200) | | max 200 — INN má nejdelší název |
|
||||||
|
| `forma` | VARCHAR(27) | | léková forma |
|
||||||
|
| `sila` | VARCHAR(24) | | síla přípravku |
|
||||||
|
| `cesta_podani` | VARCHAR(15) | | POR, INH, … |
|
||||||
|
| `baleni` | VARCHAR(22) | | **string**, ne číslo (může být "100 ks") |
|
||||||
|
| `postup_pripravy` | VARCHAR(4000) | | receptura IPLP jako volný text |
|
||||||
|
|
||||||
|
### Tabulka `predpis_slozka`
|
||||||
|
|
||||||
|
Dle `slozka_iplp_predpis_type`. Řádky vznikají jen pro IPLP předpisy se strukturovanými složkami.
|
||||||
|
|
||||||
|
| Sloupec | Typ | NOT NULL | Poznámka |
|
||||||
|
|---------|-----|----------|----------|
|
||||||
|
| `predpis_id` | INT | ✓ | FK → predpis.id |
|
||||||
|
| `mnozstvi` | DECIMAL(15,6) | ✓ | přesné množství suroviny |
|
||||||
|
| `jednotka` | ENUM('g','ks') | ✓ | |
|
||||||
|
| `nazev` | VARCHAR(200) | ✓ | název suroviny / přípravku |
|
||||||
|
| `surovina` | CHAR(7) | | kód suroviny v registru SÚKL |
|
||||||
|
| `hvlp_reg` | CHAR(7) | | pokud je složka registrovaný HVLP |
|
||||||
|
|
||||||
|
### Tabulka `vydej`
|
||||||
|
|
||||||
|
Dle `lz_nacteni_vydany_lp_erp_type`.
|
||||||
|
|
||||||
|
| Sloupec | Typ | NOT NULL | Poznámka |
|
||||||
|
|---------|-----|----------|----------|
|
||||||
|
| `id_lp_vydej` | CHAR(36) | ✓ | UUID výdeje |
|
||||||
|
| `id_lp_predpis` | CHAR(36) | | FK → predpis.id_lp_predpis, NULL = výdej bez e-předpisu |
|
||||||
|
| `kod_vydavajiciho` | VARCHAR(36) | ✓ | UUID lékárníka |
|
||||||
|
| `datum_vydeje` | DATE | ✓ | |
|
||||||
|
| `mnozstvi` | DECIMAL(6,2) | ✓ | **desetinné** — např. 0.5 balení |
|
||||||
|
| `navod` | VARCHAR(80) | ✓ | |
|
||||||
|
| `exspirace` | DATE | | exspirace šarže |
|
||||||
|
| `sarze` | VARCHAR(50) | ✓ | číslo šarže |
|
||||||
|
| `seriove_cislo` | VARCHAR(20) | | sériové číslo (léky s el. sledováním) |
|
||||||
|
| `pozn` | VARCHAR(1000) | | poznámka lékárníka |
|
||||||
|
| `typ_leku` | ENUM | | HVLPReg / HVLPNereg / IPLP |
|
||||||
|
| `lek_kod` | CHAR(7) | | kód SÚKL (HVLP) nebo KodVZP (IPLP) |
|
||||||
|
| `atc` | VARCHAR(7) | | jen HVLP |
|
||||||
|
| `nazev` | VARCHAR(146) | | |
|
||||||
|
| `forma` | VARCHAR(27) | | |
|
||||||
|
| `sila` | VARCHAR(24) | | |
|
||||||
|
| `cesta_podani` | VARCHAR(15) | | |
|
||||||
|
| `postup_pripravy` | VARCHAR(4000) | | receptura IPLP |
|
||||||
|
|
||||||
|
### Tabulka `vydej_slozka`
|
||||||
|
|
||||||
|
Dle `slozka_iplp_type`. Jako `predpis_slozka`, ale navíc obsahuje `hrazeno_zp`.
|
||||||
|
|
||||||
|
| Sloupec | Typ | NOT NULL | Poznámka |
|
||||||
|
|---------|-----|----------|----------|
|
||||||
|
| `vydej_id` | INT | ✓ | FK → vydej.id |
|
||||||
|
| `mnozstvi` | DECIMAL(15,6) | ✓ | |
|
||||||
|
| `jednotka` | ENUM('g','ks') | ✓ | |
|
||||||
|
| `nazev` | VARCHAR(200) | ✓ | název suroviny |
|
||||||
|
| `hrazeno_zp` | DECIMAL(9,2) | | částka hrazená zdravotní pojišťovnou |
|
||||||
|
| `surovina` | CHAR(7) | | |
|
||||||
|
| `hvlp_reg` | CHAR(7) | | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Klíčové vlastnosti importu (`06UlozitDoMySQL.py`)
|
||||||
|
|
||||||
|
- **Idempotentní**: `INSERT IGNORE` na `id_lp_predpis` / `id_lp_vydej` — opakované spuštění se stejným XML nepřidá duplikáty.
|
||||||
|
- **Víc pacientů**: `zprava.id_zpravy` je UNIQUE — každé volání API (jiný pacient, jiný čas) vytvoří nový řádek v `zprava`. Předpisy a výdeje napříč pacienty se agregují v `predpis` / `vydej`.
|
||||||
|
- **Schema se přepisuje**: `vytvor_schema()` vždy DROPne a znovu vytvoří všech 5 tabulek. Při produkčním použití (více pacientů) tuto část odstraňte a spouštějte DDL jen jednou při inicializaci.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Užitečné analytické dotazy
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- nejčastěji předepisované ATC skupiny za posledních 12 měsíců
|
||||||
|
SELECT atc, nazev, COUNT(*) AS pocet, MAX(datum_vystaveni) AS naposledy
|
||||||
|
FROM predpis
|
||||||
|
WHERE datum_vystaveni >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
|
||||||
|
GROUP BY atc, nazev
|
||||||
|
ORDER BY pocet DESC;
|
||||||
|
|
||||||
|
-- co bylo předepsáno ale nevyzvednuto
|
||||||
|
SELECT p.datum_vystaveni, p.nazev, p.atc, p.navod
|
||||||
|
FROM predpis p
|
||||||
|
LEFT JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
|
||||||
|
WHERE v.id_lp_vydej IS NULL;
|
||||||
|
|
||||||
|
-- IPLP magistraliter — kompletní receptury s frekvencí
|
||||||
|
SELECT p.nazev, p.postup_pripravy,
|
||||||
|
COUNT(*) AS pocet_predpisu
|
||||||
|
FROM predpis p
|
||||||
|
WHERE p.typ_leku = 'IPLP'
|
||||||
|
GROUP BY p.nazev, p.postup_pripravy
|
||||||
|
ORDER BY pocet_predpisu DESC;
|
||||||
|
|
||||||
|
-- IPLP výdeje — strukturované složky (kde je lékárna zadala)
|
||||||
|
SELECT v.datum_vydeje, v.nazev AS pripravek,
|
||||||
|
GROUP_CONCAT(s.mnozstvi, ' ', s.jednotka, ' ', s.nazev
|
||||||
|
ORDER BY s.id SEPARATOR ' + ') AS slozeni
|
||||||
|
FROM vydej v
|
||||||
|
JOIN vydej_slozka s ON s.vydej_id = v.id
|
||||||
|
WHERE v.typ_leku = 'IPLP'
|
||||||
|
GROUP BY v.id
|
||||||
|
ORDER BY v.datum_vydeje DESC;
|
||||||
|
|
||||||
|
-- nejčastěji používané suroviny v magistrech (ze strany výdeje)
|
||||||
|
SELECT nazev, jednotka, COUNT(*) AS pocet
|
||||||
|
FROM vydej_slozka
|
||||||
|
GROUP BY nazev, jednotka
|
||||||
|
ORDER BY pocet DESC;
|
||||||
|
|
||||||
|
-- párování: co předepsal lékař vs. co lékárna vydala (generická záměna)
|
||||||
|
SELECT p.datum_vystaveni,
|
||||||
|
p.nazev AS predepsano, p.atc,
|
||||||
|
v.nazev AS vydano, v.datum_vydeje
|
||||||
|
FROM predpis p
|
||||||
|
JOIN vydej v ON v.id_lp_predpis = p.id_lp_predpis
|
||||||
|
WHERE p.nazev <> v.nazev;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Závislosti (Python)
|
||||||
|
|
||||||
|
```
|
||||||
|
requests
|
||||||
|
requests-pkcs12
|
||||||
|
pymysql
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install requests requests-pkcs12 pymysql
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## XSD zdroje
|
||||||
|
|
||||||
|
Schéma verze `202501A`, soubory v `Dokumentace/2025-04-24/WSDL_XSD/NEPRIORITNI_WEBOVE_SLUZBY/`:
|
||||||
|
|
||||||
|
| Soubor | Obsah |
|
||||||
|
|--------|-------|
|
||||||
|
| `Cuer2Schema.xsd` | Typy specifické pro lékový záznam: `NacistLekovyZaznamOdpoved`, `lz_nacteni_predepsany_lp_erp_type`, `lz_nacteni_vydany_lp_erp_type`, `slozka_iplp_*` |
|
||||||
|
| `CuerSchema.xsd` | Společné typy: `hvlp_type`, `zprava_odpoved_type`, `zprava_type`, `jmeno_osoby_type`, `jednotka` |
|
||||||
Reference in New Issue
Block a user