notebookvb
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user