155 lines
6.7 KiB
Python
155 lines
6.7 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
01_zakoupeno.py — workflow status 0: Zakoupeno (datum 31.12.2024)
|
|
=================================================================
|
|
První stav reconciliačního workflow. Všem pacientům ze zakoupeného souboru
|
|
(CSV příloha smlouvy, 1712 RČ) nastaví status 0 "Zakoupeno" k 31.12.2024.
|
|
|
|
- Pacienti ze smlouvy, kteří už jsou v Mongo (registrovaní k 1.1.2025) → status 0.
|
|
- Pacienti ze smlouvy, kteří v Mongo nejsou (odhlášeni u Buzalkové před předáním)
|
|
→ doplněni z Medicus kar s markerem `mimo_vzp_populaci` + status 0.
|
|
- Pacienti v Mongo mimo smlouvu → označeni `ve_smlouve=False` (status 0 nedostanou).
|
|
|
|
Workflow stav drží:
|
|
status, status_popis, status_datum (aktuální stav)
|
|
status_historie[] (postup stavů — pro další kroky)
|
|
|
|
Idempotentní — opakované spuštění status 0 nezduplikuje.
|
|
"""
|
|
|
|
import csv
|
|
import re
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import datetime, timezone
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
import pymongo
|
|
from Knihovny.medicus_db import get_medicus_connection
|
|
|
|
# ── Konfigurace ────────────────────────────────────────────────────────────────
|
|
MONGO_URI = "mongodb://192.168.1.76:27017"
|
|
MONGO_DB = "ordinace"
|
|
MONGO_COLL = "registrovani_tracking"
|
|
CSV_PATH = Path(__file__).resolve().parent / "Inputs" / "2025-01-01 seznam_pacientu_jmeno_rc.csv"
|
|
|
|
STATUS = 0
|
|
STATUS_POPIS = "Zakoupeno"
|
|
STATUS_DATUM = "2024-12-31"
|
|
|
|
POJ_ZKR = {"111": "VZP", "201": "VoZP", "205": "ČPZP", "207": "OZP",
|
|
"209": "ZPŠ", "211": "ZPMV ČR", "213": "RBP"}
|
|
norm = lambda s: re.sub(r"\D", "", s or "")
|
|
|
|
|
|
def status_entry(now):
|
|
return {"status": STATUS, "status_popis": STATUS_POPIS,
|
|
"status_datum": STATUS_DATUM, "zapsano": now}
|
|
|
|
|
|
def main():
|
|
# ── CSV (zakoupený soubor) ──────────────────────────────────────────────────
|
|
csv_rc = {}
|
|
with CSV_PATH.open(encoding="utf-8-sig") as f:
|
|
for row in csv.DictReader(f, delimiter=";"):
|
|
csv_rc[norm(row["Rodné číslo"])] = row["Příjmení a jméno"]
|
|
contract = set(csv_rc)
|
|
print(f"Zakoupený soubor (CSV): {len(contract)} RČ")
|
|
|
|
cli = pymongo.MongoClient(MONGO_URI, serverSelectionTimeoutMS=3000)
|
|
coll = cli[MONGO_DB][MONGO_COLL]
|
|
coll.create_index("status")
|
|
coll.create_index("ve_smlouve")
|
|
|
|
pop = {norm(d["_id"]): d["_id"] for d in coll.find({}, {"_id": 1})}
|
|
popset = set(pop)
|
|
|
|
present = contract & popset
|
|
absent = contract - popset
|
|
extra = popset - contract
|
|
now = datetime.now(timezone.utc)
|
|
|
|
# ── 1) Pacienti ze smlouvy už v Mongo → status 0 (idempotentně) ─────────────
|
|
n_pres = 0
|
|
for rc in present:
|
|
_id = pop[rc]
|
|
d = coll.find_one({"_id": _id}, {"status_historie": 1})
|
|
sh = d.get("status_historie", [])
|
|
if not any(e.get("status") == STATUS for e in sh):
|
|
sh = sh + [status_entry(now)]
|
|
coll.update_one({"_id": _id}, {"$set": {
|
|
"status": STATUS, "status_popis": STATUS_POPIS, "status_datum": STATUS_DATUM,
|
|
"ve_smlouve": True, "status_historie": sh, "updated_at": now}})
|
|
n_pres += 1
|
|
|
|
# ── 2) Pacienti v Mongo mimo smlouvu → ve_smlouve = False ───────────────────
|
|
coll.update_many({"_id": {"$in": [pop[rc] for rc in extra]}},
|
|
{"$set": {"ve_smlouve": False, "updated_at": now}})
|
|
|
|
# ── 3) Pacienti ze smlouvy chybějící v Mongo → doplnit z kar + status 0 ─────
|
|
conn = get_medicus_connection()
|
|
cur = conn.cursor()
|
|
kar = {}
|
|
abslist = list(absent)
|
|
for i in range(0, len(abslist), 500):
|
|
b = abslist[i:i + 500]
|
|
ph = ",".join("?" for _ in b)
|
|
cur.execute(f"""
|
|
SELECT TRIM(k.rodcis), TRIM(k.prijmeni), TRIM(k.jmeno), TRIM(k.poj),
|
|
(SELECT MAX(r.datum_zruseni) FROM registr r JOIN icp i ON r.idicp=i.idicp
|
|
WHERE r.idpac=k.idpac AND i.icp='09305001' AND i.odb='001')
|
|
FROM kar k WHERE k.rodcis IN ({ph})""", b)
|
|
for rc, p, j, poj, zrus in cur.fetchall():
|
|
kar[(rc or "").strip()] = {"prijmeni": p, "jmeno": j,
|
|
"poj": (poj or "").strip(), "zruseni": zrus}
|
|
conn.close()
|
|
|
|
n_ins = 0
|
|
for rc in absent:
|
|
if coll.find_one({"_id": rc}):
|
|
continue
|
|
k = kar.get(rc, {})
|
|
poj = k.get("poj", "")
|
|
zrus = k.get("zruseni")
|
|
zrus_s = zrus.strftime("%Y-%m-%d") if zrus else None
|
|
snap = {
|
|
"k_datu": "2025-01-01", "kategorie": "ODHLASEN_PRED_PREDANIM",
|
|
"kategorie_popis": "Registrace u Buzalkové zrušena před předáním (1.1.2025)",
|
|
"v_zakoupenem_souboru": False,
|
|
"flag": "NEBYL V ZAKOUPENÉM SOUBORU PACIENTŮ",
|
|
"flag_duvod": f"registrace u Buzalkové zrušena {zrus_s} (před předáním)",
|
|
"praktik_nazev": None, "praktik_icz": None, "praktik_icp": None,
|
|
"praktik_od": None, "datum_zahajeni": None, "datum_ukonceni": None,
|
|
"medicus_zruseni": zrus_s,
|
|
}
|
|
coll.insert_one({
|
|
"_id": rc, "rc": rc,
|
|
"prijmeni": k.get("prijmeni"), "jmeno": k.get("jmeno"),
|
|
"pojistovna": {"kod": poj, "zkratka": POJ_ZKR.get(poj, poj)},
|
|
"medicus_poj": poj,
|
|
"status": STATUS, "status_popis": STATUS_POPIS, "status_datum": STATUS_DATUM,
|
|
"ve_smlouve": True, "mimo_vzp_populaci": True,
|
|
"vychozi_datum": "2025-01-01", "aktualni": snap,
|
|
"historie": [{**snap, "zmena": "doplněn ze smlouvy (mimo VZP populaci)"}],
|
|
"status_historie": [status_entry(now)],
|
|
"created_at": now, "updated_at": now,
|
|
})
|
|
n_ins += 1
|
|
|
|
# ── Souhrn ──────────────────────────────────────────────────────────────────
|
|
print(f"present (status 0 nastaveno) : {n_pres}")
|
|
print(f"absent doplněno ze smlouvy (insert) : {n_ins}")
|
|
print(f"extra mimo smlouvu (ve_smlouve=False): {len(extra)}")
|
|
print()
|
|
print(f"status 0 (Zakoupeno) celkem : {coll.count_documents({'status': 0})}")
|
|
print(f"ve_smlouve = True : {coll.count_documents({'ve_smlouve': True})}")
|
|
print(f"kolekce celkem : {coll.count_documents({})}")
|
|
cli.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|