notebookvb

This commit is contained in:
Vladimir Buzalka
2026-04-29 06:51:47 +02:00
parent a1b9c93506
commit a9c143ba24
141 changed files with 30711 additions and 0 deletions
+321
View File
@@ -0,0 +1,321 @@
# MedicusWithClaudePN Pracovní neschopnosti
## Účel
Report aktivních pracovních neschopností pro MUDr. Buzalkovou Michaelu.
Generuje PDF a odesílá na výchozí tiskárnu.
## Spuštění
```bash
# Test otevře PDF v prohlížeči, netiskne:
python pn_report.py --no-print
# Ostrý provoz vytiskne rovnou na výchozí tiskárnu:
python pn_report.py
```
## Požadavky
```bash
pip install reportlab pywin32
```
## SQL dotaz aktivní PN
Zachycen přes Firebird trace přímo z Medicusu (přesná kopie logiky aplikace),
doplněn o podotaz na poslední 14denní potvrzení z tabulky HPN.
```sql
SELECT
nes.id,
nes.idpac,
TRIM(kar.prijmeni) || ', ' || TRIM(kar.jmeno) AS jmeno,
kar.rodcis,
nes.zacnes,
nes.konnes,
nes.diagno,
COALESCE(nes.ecn, nes.cisnes) AS cisnes,
(SELECT MAX(h.datum) FROM hpn h
WHERE h.idnes = nes.id AND h.typ = '2' AND h.storno = 'F') AS posl_potvrzeni
FROM nes, kar
WHERE nes.zacnes <= current_date
AND nes.konnes IS NULL
AND nes.idpac = kar.idpac
AND nes.pracne = 'A'
AND nes.storno <> 'T'
AND (
NOT EXISTS (SELECT id FROM nesd WHERE nesd.idnes = nes.id)
OR (SELECT FIRST 1 kam FROM nesd WHERE nesd.idnes = nes.id
ORDER BY nesd.datum DESC, nesd.id DESC) = 'N'
)
ORDER BY kar.prijmeni ASC, kar.jmeno ASC
```
### Klíčové podmínky
| Podmínka | Význam |
|---|---|
| `pracne = 'A'` | Pouze pracovní neschopnosti (ne jiné typy) |
| `storno <> 'T'` | Vyřazení stornovaných záznamů |
| `zacnes <= current_date` | PN již začala |
| `konnes IS NULL` | PN dosud neskončila datum konce nemůže být v budoucnosti (pravidlo ČSSZ), aktivní PN má vždy `konnes = NULL` |
| `nesd` subquery | PN nebyla předána dál poslední záznam `Kam = 'N'` = stále u pacienta |
| `COALESCE(ecn, cisnes)` | Použije ECN (elektronické), jinak starší CISNES |
## Sloupce reportu
| Sloupec | Zdroj | Poznámka |
|---|---|---|
| # | | Pořadové číslo |
| Příjmení a jméno | KAR | |
| Rod. číslo | KAR | |
| Začátek PN | NES.ZACNES | |
| Dnů | výpočet | Počet dní od začátku PN do dnes |
| Diagnóza | NES.DIAGNO | |
| Posl. potvrzení | HPN (TYP='2') | Datum posledního 14denního potvrzení |
| Dní od potvr. | výpočet | Červeně pokud > 14 dní |
## Tabulka HPN typy podání
| TYP | Význam |
|---|---|
| `H` | Hlášení neschopnosti (vznik PN) |
| `1` | První zpráva |
| `P` | **Průběžná zpráva = 14denní potvrzení trvání PN** |
| `2` | Neznámý typ (2033 záznamů v DB, ale ne pro průběžná potvrzení) |
| `C`, `Y`, `Z` | Vzácné typy (jednotky záznamů) |
Vazba: `HPN.IDNES → NES.ID`
---
## Jak Medicus zobrazuje PN daného pacienta (zachyceno z trace)
### 1. Seznam všech PN pacienta
```sql
SELECT
ID, IDPAC, DATNES, CISNES, PODNIK, ADRESA, PROFES, ZACNES,
KONNES, PRACNE, PRICINA, DIAGNO, KONDIA, PREDAN, IDUZI,
VYSTAVIL, DATUKONNES, IDODD, IDPRAC, STORNO,
DATVYCHOD, DATVYCHDO, VYCH1OD, VYCH1DO, VYCH2OD, VYCH2DO, VYCH3OD, VYCH3DO,
DATOSETRENI, DATPRINAV, OMLUVENKA, RODCISNES,
DatNastUstPece, DatUkonUstPece, ICPE, ECN, EPODANI,
ADR_OBEC, ADR_CP, ADR_CO, ADR_DOD, ADR_PSC, ADR_STAT,
ZAM_ADRESA, DATUKON_OSSZ, ZAMDRUH, STATDPNKOD,
SOUHLAS_SSZKOD, SOUHLAS_SSZNAZ, SOUHLAS_DATUM,
DGZMENA, CIZI, OSSZ, DUVOD_UKONCENI, UKON_OSSZ, PORUS_REZIMU,
UKON_OSSZNAZ, ADR_ZMENA, coalesce(ECN, CISNES) as CISLO,
ADR_ZMENA_DO, POTVRZENI_VYDANO, DATNAR, SPRAVCE_POJ,
ZAM_OBEC, ZAM_CO, ZAM_CP, ZAM_DOD, ZAM_PSC, ZAM_STAT, ZAM_CCSZ_ID, ZAM_CSSZ_VARSYM,
VYCHINDIVIDUAL, VERZE_DPN, LEKAR_VYSTAVIL, LEKAR_VYSTAVIL_ICPE,
USEDATNAR, KONTAKT_TEL, KONTAKT_EMAIL,
case when KONTAKT_TEL is not NULL then 'S'
when KONTAKT_EMAIL is not null then 'E'
else NULL end as NOTIFIKACE,
coalesce(KONTAKT_TEL, KONTAKT_EMAIL) as NOTIFIKACE_KONTAKT
FROM NES
WHERE IDPAC = ?
ORDER BY DATNES ASC, ID ASC
```
### 2. Formuláře eNeschopenky pro vybranou PN (záložka "Formuláře eNeschopenky")
Zobrazuje pouze TYP `H`, `1`, `2` (ne `P` = propuštění).
Pouze záznamy s vazbou na HISTDOC (`IDHISTDOC IS NOT NULL`).
```sql
SELECT
HD.ID AS HISTDOCID,
H.TYP AS HISTDOCTYP, -- H=hlášení, 1=první zpráva, 2=průběžná/potvrzení
HD.DATUM AS DATZAD, -- Datum vystavení (z HISTDOC)
H.DATUM AS DATPOD, -- Datum podání (z HPN)
H.STAV,
H.ODBAVENO,
HD.TYP
FROM HPN H
JOIN HISTDOC HD ON H.IDHISTDOC = HD.ID
WHERE H.IDNES = ?
ORDER BY HD.DATUM ASC
```
### 3. Rychlý přehled formulářů (bez HISTDOC)
Používá se pro zjištění stavu vrací všechny záznamy TYP `H`, `1`, `2`:
```sql
SELECT * FROM HPN
WHERE IDNES = ?
AND STORNO = 'F'
AND TYP IN ('1', '2', 'H')
ORDER BY DATUM DESC, CAS DESC, ID DESC
```
### 4. TFHpnHistorie formulář "Historie HPN" (acHpnHistorie)
Kompletní přehled všech HPN záznamů pro vybranou PN. Spouští se akcí `acHpnHistorie`.
```sql
select h.ID, h.IDNES, h.IDPODANI, h.TYP, h.DATA, h.DATUM, h.CAS, h.ODPOVED,
h.IDPRAC, h.IDUZI, h.UPRAVENO, h.OPRAVA_ID, h.STAV, h.STORNO,
h.POR_CISLO, h.ID_CHYBY, h.OSSZ,
n.CisNes, n.Ecn, coalesce(n.CisNes, n.Ecn) as Cislo, n.IdPac,
k.Prijmeni, k.Jmeno, k.Titul, coalesce(n.RODCISNES, k.RODCIS) as RODCIS,
u.Zkratka, hp.Odeslano, hp.CorelationId,
(select first 1 h2.ID from HPN h2 where h2.OPRAVA_ID = h.ID) as IdOpravy,
h.verze_dpn,
n.SPRAVCE_POJ,
n.ADRESA as ULICE, n.ADR_CP, n.ADR_CO, n.ADR_DOD, n.ADR_OBEC, n.ADR_PSC, n.ADR_STAT,
n.PODNIK, n.PROFES, n.ZAM_ADRESA, n.ZAM_CP, n.ZAM_CO, n.ZAM_OBEC, n.ZAM_PSC, n.ZAM_STAT,
n.ZACNES, n.DIAGNO, n.DATNES, n.PRICINA,
n.KONNES, n.KONDIA, n.DATUKONNES,
n.DATVYCHOD, n.VYCH1OD, n.VYCH1DO, n.VYCH2OD, n.VYCH2DO,
n.PRICINA, n.ICPE, n.VYCH3OD, n.VYCH3DO, n.KONTAKT_TEL,
h.IDHISTDOC, h.ODBAVENO,
IIF((H.IDHISTDOC is not null),
(select HD.TYP from HISTDOC HD where HD.ID = H.IDHISTDOC), null) as HISTDOCTYP
from HPN h
left join NES n on (n.id = h.idnes)
left join KAR k on (k.IdPac = n.IdPac)
left join UZIVATEL u on (u.IdUzi = h.IdUzi)
left join HPN_PODANI hp on (hp.ID = h.IdPodani)
where h.IdNes = ?
ORDER BY h.Datum ASC, h.Cas ASC, h.Id ASC
```
### 5. Kontrola čekajících podání (PN s neodeslanými HPN záznamy)
```sql
select nes.id from nes
where nes.idpac = ?
and nes.storno = 'F'
and nes.epodani = 'T'
and nes.icpe = ?
and coalesce(nes.verze_dpn, '') not in ('', 'p', 'o')
and exists (
select 1 from hpn
where hpn.idnes = nes.id
and hpn.storno = 'F'
and hpn.typ in ('1', '2', 'H')
and hpn.idpodani is null -- dosud neodesláno
and hpn.stav <> 99
and hpn.stav <> 10
)
```
### 6. Kontrola potvrzení vydaného tento měsíc (POTVRZENI_VYDANO)
Medicus kontroluje zda pro daného pacienta existuje PN aktivní alespoň 10 dní,
u které ještě nebylo vydáno potvrzení v aktuálním měsíci:
```sql
select first 1 ZACNES, CISNES, ID, POTVRZENI_VYDANO
from NES
where (IDPAC = ?)
and (? >= ZACNES + 10) -- PN trvá alespoň 10 dní
and ((KONNES is NULL) or (KONNES > ?))
and (STORNO = 'F')
and (
extract(month from POTVRZENI_VYDANO) || extract(year from POTVRZENI_VYDANO)
=
extract(month from cast(? as date)) || extract(year from cast(? as date))
)
```
### 7. Vyhledání HPN záznamu podle ICPE v XML datech
Číslo `11031812` (ICPE lékaře) se hledá přímo v obsahu XML blobu `HPN.DATA`.
Medicus takto identifikuje konkrétní HPN záznam při opravě nebo ověření stavu:
```sql
-- Neodeslané nebo čekající záznamy:
select h.id from HPN h
left join HPN h2 on (h2.OPRAVA_ID = h.ID)
where (h.storno = 'F')
and ((h.stav in (0,1)) or (h.stav is NULL))
and (h2.OPRAVA_ID is null)
and (H.DATA containing '11031812') -- hledá ICPE v XML obsahu
and (h.IDNES = ?)
-- Úspěšně odeslané záznamy (stav=1):
select h.id from HPN h
left join HPN h2 on (h2.OPRAVA_ID = h.ID)
where (h.storno = 'F')
and (h.stav = 1)
and h2.OPRAVA_ID is null
and (H.DATA containing '11031812')
and h.IDNES = ?
```
### 8. Předání/Převzetí (záložka "Předání/Převzetí")
```sql
SELECT ID, IDNES, KAMODKUD, DATUM, KAM, ICZ, ICPE, ICO, JMENO_LEKARE
FROM NESD
WHERE IDNES = ?
ORDER BY DATUM ASC, ID ASC
```
### Poznámky
- **HISTDOC** každé odeslání formuláře vytváří záznam v HISTDOC; HPN bez IDHISTDOC se v UI nezobrazí
- **HPN.STAV** stav podání (1 = odesláno/přijato)
- **HPN.ODBAVENO** příznak zpracování (`'F'` = ne, `'T'` = ano)
- HPN záznamy TYP='2' (průběžná potvrzení) **nemají IDHISTDOC** JOIN s HISTDOC by je odfiltroval. Pro datum posledního potvrzení v reportu proto používáme prostý MAX bez JOINu. HISTDOC mají pouze TYP='P' (ukončení PN).
---
## Vazby tabulky NES (zjištěno z DB)
### Formální FK constrainty
| Směr | Vazba | Popis |
|---|---|---|
| NES → KAR | `NES.IDPAC → KAR.IDPAC` | Každá neschopenka patří pacientovi v kartotéce |
| HPN → NES | `HPN.IDNES → NES.ID` | Formuláře/hlášení HPN odkazují na konkrétní neschopenku |
### Logické vazby (bez FK constraintu)
| Tabulka | Pole | Poznámka |
|---|---|---|
| NESD | `NESD.IDNES → NES.ID` | Předání/převzetí PN vazba jen kódem, ne constraintem |
| HISTDOC | `HPN.IDHISTDOC → HISTDOC.ID` | Dokumenty k formulářům vazba přes HPN |
### Indexy na NES
| Index | Unique | Pole |
|---|---|---|
| PK_NES | Ano | ID |
| FK_NES_KAR | Ne | IDPAC |
| NES_POTVRZENI_VYDANO | Ne | POTVRZENI_VYDANO |
### Poznámka
Medicus obecně používá minimum DB constraintů většina vazeb je řešena aplikačním kódem.
`NESD` a `HISTDOC` nemají formální FK na `NES`, přesto jsou klíčové pro zobrazení PN v UI.
---
## Červené zvýraznění
Sloupce "Posl. potvrzení" a "Dní od potvr." jsou červeně zvýrazněny pokud:
- Od posledního potvrzení uplynulo více než 14 dní, nebo
- PN nemá žádné potvrzení a trvá déle než 14 dní (zobrazí se s `(!)`)
## Tisk
Skript používá `win32api.ShellExecute` s příkazem `'print'` odešle PDF
na výchozí tiskárnu Windows.
## Automatizace
Plánované spouštění každé pondělí a pátek ráno přes Windows Task Scheduler
zatím nenastaveno, připravit až bude skript stabilní.
## Soubory
| Soubor | Obsah |
|---|---|
| `pn_report.py` | Hlavní skript DB dotaz, generování PDF, tisk |
| `PN.md` | Tento soubor dokumentace |