notebookvb

This commit is contained in:
2026-04-06 07:31:49 +02:00
parent ad4d5b8dac
commit 921c69e908
26 changed files with 15260 additions and 21 deletions
@@ -0,0 +1,13 @@
User-Agent: Medicus
Host: lekar-soap.erecept.sukl.cz
SOAPAction: "NacistPredpis"
Content-Type: text/xml; charset="UTF-8"
Authorization: Basic ZTA4Yzg5YzYtMmIxYS00ZWJhLThlZDktNGUzZTYzNjE4Mzc5OkJ1emFsa2FAVmxhZGltaXIyMDI1
Content-Length: 643
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NacteniPredpisuDotaz xmlns="http://www.sukl.cz/erp/201704"><Doklad><Pristupujici><Uzivatel>E08C89C6-2B1A-4EBA-8ED9-4E3E63618379</Uzivatel><Pracoviste>00214235367</Pracoviste></Pristupujici><Identifikator><ID_Dokladu>PPIBVF93285E</ID_Dokladu></Identifikator></Doklad><Zprava><ID_Zpravy>bf002578-4e0d-48f9-86b4-ea3e21f280ec</ID_Zpravy><Verze>202501A</Verze><Odeslano>2026-04-05T15:24:10+02:00</Odeslano><SW_Klienta>MEDICUS_____</SW_Klienta></Zprava></NacteniPredpisuDotaz>
</soapenv:Body>
</soapenv:Envelope>
@@ -0,0 +1,283 @@
# NacistPredpis — Funkční SOAP klient pro IS eRecept SÚKL
## Status
**OVĚŘENO FUNKČNÍ** — 6. dubna 2026
Odpověď serveru: `HTTP 200`, velikost: ~3.7 KB
Schéma ověřeno proti: `schema1.xsd` verze `202501A` (dokumentace SÚKL 2025-04-24)
Debug ověřen z: `MedicusDebug/eR_SuklMesage_bf002578-*.mime`
---
## Co tato operace dělá
`NacistPredpis` je SOAP operace IS eRecept (SÚKL), která vrátí **kompletní detail jednoho konkrétního receptu** podle jeho ID.
Vrací vše: pacienta (jméno, adresa, rodné číslo, ZP), lékaře, ordinaci, předepsaný lék (ATC, dávkování, úhrada), stav receptu, výdej z lékárny.
Typické použití: lékař si zobrazí detail receptu, který sám vystavil, nebo ověří zda byl vydán.
---
## Klíčové informace
### Endpoint (produkce)
```
https://lekar-soap.erecept.sukl.cz/cuer/Lekar
```
> Tato operace je na **starším** endpointu `/cuer/Lekar` — **bez** číslice 2.
> Operace `NacistLekovyZaznam` je naopak na `/cuer/Lekar2`.
### Endpoint (testovací prostředí)
```
https://lekar-soap.test-erecept.sukl.cz/cuer/Lekar
```
### SOAPAction
```
"NacistPredpis"
```
### XML namespace
```
http://www.sukl.cz/erp/201704
```
> Starší namespace z roku 2017 — tato operace existuje od počátku IS eRecept.
> Na rozdíl od `NacistLekovyZaznam` (namespace `201912`) zde zůstává `201704`.
---
## Porovnání s NacistLekovyZaznam
| | NacistPredpis | NacistLekovyZaznam |
|---|---|---|
| **Namespace** | `201704` | `201912` |
| **Endpoint** | `/cuer/Lekar` | `/cuer/Lekar2` |
| **SOAPAction** | `NacistPredpis` | `NacistLekovyZaznam` |
| **Identifikace** | ID receptu (alfanumerický kód) | jméno + datum narození pacienta |
| **Výsledek** | detail jednoho receptu | celý lékový záznam pacienta (roky) |
| **Velikost odpovědi** | ~3.7 KB | ~227 KB |
---
## Autentizace (dvojitá — stejná jako u všech operací)
### 1. Klientský certifikát (TLS mutual auth)
- Soubor: `AMBSUKL214235369G_31DEC2024.pfx`
- Formát: PKCS#12 (`.pfx`)
- Knihovna: `requests-pkcs12``Pkcs12Adapter`
### 2. HTTP Basic Auth
- Uživatel: UUID lékaře
- Heslo: osobní heslo lékaře do portálu eRecept
---
## Struktura SOAP dotazu
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<NacteniPredpisuDotaz xmlns="http://www.sukl.cz/erp/201704">
<Doklad>
<Pristupujici>
<Uzivatel>E08C89C6-2B1A-4EBA-8ED9-4E3E63618379</Uzivatel> <!-- UUID lékaře -->
<Pracoviste>00214235367</Pracoviste> <!-- IČP pracoviště -->
</Pristupujici>
<Identifikator>
<ID_Dokladu>PPIBVF93285E</ID_Dokladu> <!-- ID receptu, 1225 znaků -->
<!-- alternativně: -->
<!-- <ID_Podani>uuid-guid-formát</ID_Podani> -->
</Identifikator>
</Doklad>
<Zprava>
<ID_Zpravy>bf002578-4e0d-48f9-86b4-ea3e21f280ec</ID_Zpravy>
<Verze>202501A</Verze>
<Odeslano>2026-04-06T07:24:04+00:00</Odeslano>
<SW_Klienta>MEDICUS_____</SW_Klienta>
</Zprava>
</NacteniPredpisuDotaz>
</soapenv:Body>
</soapenv:Envelope>
```
### Parametry dotazu (ověřeno proti schema1.xsd verze 202501A)
| Element | Povinný | Omezení | Poznámka |
|---|---|---|---|
| `Uzivatel` | ✅ ano | UUID formát | UUID lékaře přidělené SÚKL |
| `Pracoviste` | ✅ ano | — | IČP pracoviště lékaře |
| `ID_Dokladu` | ❌ volitelný* | 1225 znaků | alfanumerický kód receptu |
| `ID_Podani` | ❌ volitelný* | UUID formát (36 znaků) | alternativní identifikátor podání |
| `ID_Zpravy` | ✅ ano | UUID formát | nové UUID pro každý dotaz |
| `Verze` | ✅ ano | — | aktuálně `202501A` |
| `Odeslano` | ✅ ano | ISO 8601 | čas odeslání s časovou zónou |
| `SW_Klienta` | ✅ ano | přesně 12 znaků | doplnit mezerami |
> *Uvést právě jedno z: `ID_Dokladu` nebo `ID_Podani` — viz chybový kód L001.
### Formát ID receptu (`ID_Dokladu`)
Alfanumerický kód délky 1225 znaků, např. `PPIBVF93285E`.
- Nesmí obsahovat písmena O (zaměnitelné s nulou), I (zaměnitelné s jedničkou), Y, Z
- Nesmí obsahovat malá písmena ani diakritiku
- Lékař jej vidí na průvodce receptu / v Medicusu
---
## Struktura odpovědi (ověřeno proti schema1.xsd verze 202501A)
```
NacteniPredpisuOdpoved
├── Doklad
│ ├── ID_Dokladu alfanumerický kód receptu
│ ├── DatumVystaveni datum
│ ├── PlatnostDo datum
│ ├── VypisDo datum — volitelný (prodloužená platnost výpisem)
│ ├── Akutni boolean — volitelný
│ ├── Rodina boolean — volitelný
│ ├── Preshranicni boolean — volitelný
│ ├── Opakovani int — volitelný (opakovací předpis)
│ │
│ ├── Pacient
│ │ ├── Totoznost
│ │ │ ├── Jmeno (Prijmeni, Jmena)
│ │ │ ├── DatumNarozeni
│ │ │ ├── Adresa (ulice, číslo, obec, PSC, okres...)
│ │ │ └── ROB způsob ztotožnění: ECD / JPDN / JPDNA
│ │ ├── CP číslo pojištěnce (rodné číslo)
│ │ ├── ZP Kod + Nazev zdravotní pojišťovny
│ │ ├── Telefon volitelný
│ │ ├── Notifikace SMS / Email — volitelný
│ │ └── Pohlavi M / Z — volitelný
│ │
│ ├── Predepisujici
│ │ ├── Lekar Kod (UUID) + Jmeno
│ │ ├── ICZ 8 číslic
│ │ ├── ICP 8 číslic
│ │ ├── PZS Kod + Nazev + IC + Telefon + Adresa
│ │ ├── Telefon
│ │ ├── Email volitelný
│ │ └── Odbornost Kod + Nazev
│ │
│ ├── Doporucujici volitelný — doporučující lékař
│ │ ├── Jmeno
│ │ ├── PZS
│ │ └── Odbornost
│ │
│ ├── Revize volitelný — schválení revizním lékařem ZP
│ │
│ ├── PLP[] předepsané léčivé přípravky (1 nebo více)
│ │ ├── Mnozstvi int, 19999
│ │ ├── Navod dávkování, max 80 znaků (např. "1-1-0")
│ │ ├── Uhrada ZAKLADNI / ZVYSENA / NEHRAZENY
│ │ ├── HVLPReg volitelný — registrovaný lék
│ │ │ ├── Kod SÚKL kód (7 číslic, např. "0087076")
│ │ │ ├── ATC ATC kód (např. "R05CB15")
│ │ │ ├── Nazev např. "ERDOMED"
│ │ │ ├── Forma léková forma (např. "CPS DUR")
│ │ │ ├── Sila síla (např. "300MG")
│ │ │ ├── CestaPodani např. "POR"
│ │ │ └── Baleni počet kusů v balení
│ │ ├── HVLPNereg volitelný — neregistrovaný HVLP
│ │ ├── IPLP volitelný — individuálně připravovaný LP
│ │ ├── INN volitelný — generický název
│ │ ├── Prekroceni boolean — překročení limitu
│ │ ├── ID_LP_Zdroj int — ID zdroje LP
│ │ └── ID_LP UUID položky předpisu
│ │
│ ├── Pozn poznámka, max 1000 znaků — volitelný
│ ├── Stav stav receptu (viz níže)
│ │
│ ├── Vydej[] volitelný — výdeje z lékáren (zkrácená forma)
│ │ ├── ID_Dokladu ID výdeje
│ │ ├── ID_Dokladu_ERP ID receptu (zpětný odkaz)
│ │ ├── DatumVydeje datum
│ │ ├── NazevPZS název lékárny
│ │ ├── JmenoVydavajiciho jméno lékárníka (může být "skryto")
│ │ ├── VLP[] vydané léčivé přípravky
│ │ │ ├── Mnozstvi
│ │ │ ├── Nazev plný název léku (např. "ERDOMED 300MG CPS DUR 20")
│ │ │ ├── Kod SÚKL kód
│ │ │ ├── Navod
│ │ │ └── IdLpErp UUID zpětný odkaz na PLP
│ │ ├── Zmena datetime
│ │ └── Zalozeni datetime
│ │
│ ├── Zmena datetime — poslední změna receptu
│ ├── Zalozeni datetime — vytvoření receptu
│ ├── DruhPojisteni VEREJNE / OSTATNI — volitelný
│ ├── ModryPruh boolean — volitelný (omamné látky)
│ ├── Papirovy boolean — volitelný
│ └── ZapocitatelnyDoplatekZbyvaDoLimitu decimal — zbývající limit doplatků pacienta
└── Zprava
├── ID_Zpravy nové UUID od serveru
├── Verze
├── Odeslano
├── ID_Podani echo ID podání
└── Prijato datetime — čas přijetí na serveru
```
### Hodnoty stavu receptu (`Stav`)
| Hodnota | Popis |
|---|---|
| `KE_SCHVALENI` | čeká na schválení revizním lékařem ZP |
| `ZAMITNUTY` | zamítnut |
| `PREDEPSANY` | vystaven, čeká na výdej |
| `PRIPRAVOVANY` | lékárna si ho načetla, připravuje výdej |
| `CASTECNE_VYDANY` | vydán částečně (opakovací předpis) |
| `PLNE_VYDANY` | kompletně vydán ✅ |
| `NEDOKONCENY_VYDEJ` | výdej nedokončen |
| `UZAVRENY` | uzavřen, nelze měnit |
### Hodnoty způsobu ztotožnění (`ROB`)
| Hodnota | Popis |
|---|---|
| `ECD` | elektronicky čitelný doklad (občanský průkaz/pas) |
| `JPDN` | jednoznačný dle jména, příjmení, data a adresy |
| `JPDNA` | jednoznačný dle jména, příjmení a data (bez adresy) |
---
## HTTP hlavičky
```python
headers = {
"Content-Type": 'text/xml; charset="UTF-8"',
"SOAPAction": '"NacistPredpis"', # uvozovky jsou součástí hodnoty!
"User-Agent": "Medicus"
}
```
---
## Závislosti (Python)
```
requests
requests-pkcs12
```
---
## Soubor skriptu
`NacistPredpis_FUNKCNI.py` — funkční implementace, ověřeno 6. 4. 2026.
---
## Zdroje dokumentace SÚKL
| Soubor | Datum | Obsah |
|---|---|---|
| `MedicusDebug/eR_PostData.xml` | 2026-04-05 | reálný dotaz z Medicusu |
| `MedicusDebug/eR_SuklMesage_*.mime` | 2026-04-05 | HTTP hlavičky + tělo dotazu |
| `MedicusDebug/eR_SuklMesage_*_Resp.xml` | 2026-04-05 | reálná odpověď serveru |
| `CUERLekar.wsdl` | 2025-04-24 | definice operace NacistPredpis |
| `schema1.xsd` | 2025-04-24 | kompletní XSD schéma dotazu i odpovědi |
@@ -0,0 +1,71 @@
import uuid
from datetime import datetime, timezone
from requests import Session
from requests_pkcs12 import Pkcs12Adapter
# --- Konfigurace ---
PFX_FILE = r"C:\Users\vlado\PycharmProjects\Recepty\AMBSUKL214235369G_31DEC2024.pfx"
PFX_PASSWORD = "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/Lekar"
NAMESPACE = "http://www.sukl.cz/erp/201704"
# --- ID receptu ---
# Alfanumerický kód receptu, např. PPIBVF93285E
ID_DOKLADU = "PPIBVF93285E"
def nacist_predpis():
sess = Session()
sess.mount("https://", Pkcs12Adapter(pkcs12_filename=PFX_FILE, pkcs12_password=PFX_PASSWORD))
sess.auth = (API_USER, API_PASS)
id_zpravy = str(uuid.uuid4())
odeslano = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S+00:00")
soap_body = (
'<?xml version="1.0" encoding="UTF-8"?>'
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">'
'<soapenv:Body>'
f'<NacteniPredpisuDotaz xmlns="{NAMESPACE}">'
f'<Doklad>'
f'<Pristupujici>'
f'<Uzivatel>{UZIVATEL}</Uzivatel>'
f'<Pracoviste>{PRACOVISTE}</Pracoviste>'
f'</Pristupujici>'
f'<Identifikator>'
f'<ID_Dokladu>{ID_DOKLADU}</ID_Dokladu>'
f'</Identifikator>'
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'</NacteniPredpisuDotaz>'
'</soapenv:Body>'
'</soapenv:Envelope>'
)
headers = {
"Content-Type": 'text/xml; charset="UTF-8"',
"SOAPAction": '"NacistPredpis"',
"User-Agent": "Medicus"
}
print(f"Recept: {ID_DOKLADU}")
print(f"Volám: {ENDPOINT}\n")
resp = sess.post(ENDPOINT, data=soap_body.encode("utf-8"), headers=headers, timeout=15)
print(f"HTTP {resp.status_code} | {len(resp.content)} bytů\n")
print(resp.text)
if __name__ == "__main__":
nacist_predpis()