notebookVB

This commit is contained in:
2026-01-26 19:46:49 +01:00
parent b20654b607
commit 73e5eab4a4
4 changed files with 476 additions and 0 deletions

View File

@@ -0,0 +1,234 @@
import re
from pathlib import Path
from typing import List, Dict, Set
import pymysql
from knihovny.medicus_db import MedicusDB
# ============================================================
# KONFIGURACE
# ============================================================
# --- Firebird / Medicus ---
FIREBIRD_HOST = "192.168.1.4"
FIREBIRD_DB = r"Z:\medicus 3\data\medicus.fdb"
FIREBIRD_USER = "SYSDBA"
FIREBIRD_PASS = "masterkey"
FIREBIRD_CHARSET = "WIN1250"
# --- MySQL / Kapitace ---
MYSQL_CFG = {
"host": "192.168.1.76",
"port": 3307,
"user": "root",
"password": "Vlado9674+",
"database": "ordinace",
"charset": "utf8mb4",
"autocommit": True,
}
MYSQL_TABLE_HEADER = "zp_kapitace_header"
MYSQL_TABLE_PAC = "zp_kapitace_pojistenec"
# ============================================================
# HELPERY
# ============================================================
_rc_re = re.compile(r"\D+")
def normalize_rc(value: str) -> str:
"""Rodné číslo / číslo pojištěnce → jen číslice."""
if not value:
return ""
return _rc_re.sub("", str(value))
def parse_kapdetail_idpacs(kapdetail: str) -> List[int]:
"""
KAPDETAIL:
<něco>=SOUHRN;idpac;vek|castka;idpac;vek|castka;...
Vrací seznam idpac.
"""
if not kapdetail:
return []
s = kapdetail.strip()
if "=" in s:
s = s.split("=", 1)[1]
parts = [p.strip() for p in s.split(";") if p.strip()]
if not parts:
return []
# první položka je souhrn (není idpac)
if not parts[0].isdigit():
parts = parts[1:]
idpacs: List[int] = []
# idpac je vždy na sudém indexu (0,2,4,...)
for i in range(0, len(parts), 2):
if parts[i].isdigit():
idpacs.append(int(parts[i]))
return idpacs
def chunk_list(lst: List[int], size: int = 500) -> List[List[int]]:
return [lst[i:i + size] for i in range(0, len(lst), size)]
# ============================================================
# FIREBIRD DATA Z MEDICUSU
# ============================================================
def get_latest_fak_for_poj(db: MedicusDB, poj: str) -> Dict:
sql = """
SELECT
fak.id,
fak.cisfak,
fak.poj,
fak.kapdetail
FROM fak
WHERE fak.poj = ?
AND fak.kapdetail IS NOT NULL
AND fak.kapdetail <> ''
ORDER BY fak.cisfak DESC
ROWS 1
"""
rows = db.query_dict(sql, (poj,))
return rows[0] if rows else {}
def get_rodcis_for_idpacs(db: MedicusDB, idpacs: List[int]) -> Dict[int, str]:
"""
Vrátí mapu: idpac → rodcis
"""
result: Dict[int, str] = {}
if not idpacs:
return result
for batch in chunk_list(idpacs):
placeholders = ",".join("?" for _ in batch)
sql = f"""
SELECT
kar.idpac,
kar.rodcis
FROM kar
WHERE kar.idpac IN ({placeholders})
AND kar.rodcis IS NOT NULL
AND kar.rodcis <> ''
AND (kar.vyrazen IS NULL OR kar.vyrazen <> 'A')
"""
rows = db.query(sql, tuple(batch))
for idpac, rodcis in rows:
result[int(idpac)] = str(rodcis)
return result
# ============================================================
# MYSQL KAPITACE ZP
# ============================================================
def get_mysql_kapitace_rc(zp_kod: str) -> Set[str]:
sql = f"""
SELECT p.cislo_pojistence
FROM {MYSQL_TABLE_PAC} p
JOIN {MYSQL_TABLE_HEADER} h ON h.id = p.header_id
WHERE h.zp_kod = %s
AND h.snapshot_date = (
SELECT MAX(h2.snapshot_date)
FROM {MYSQL_TABLE_HEADER} h2
WHERE h2.zp_kod = %s
)
"""
with pymysql.connect(**MYSQL_CFG) as conn:
with conn.cursor() as cur:
cur.execute(sql, (zp_kod, zp_kod))
rows = cur.fetchall()
return {
normalize_rc(r[0])
for r in rows
if normalize_rc(r[0])
}
# ============================================================
# MAIN
# ============================================================
def main():
poj = input("Zadej kód pojišťovny (např. 207): ").strip()
# --- Medicus ---
mdb = MedicusDB(
host=FIREBIRD_HOST,
db_path=FIREBIRD_DB,
user=FIREBIRD_USER,
password=FIREBIRD_PASS,
charset=FIREBIRD_CHARSET,
)
fak = get_latest_fak_for_poj(mdb, poj)
if not fak:
print(f"❌ Nenalezena žádná kapitační faktura pro pojišťovnu {poj}")
mdb.close()
return
print("\nNalezena faktura:")
print(f" ID : {fak['id']}")
print(f" CISFAK : {fak['cisfak']}")
print(f" POJ : {fak['poj']}")
idpacs = parse_kapdetail_idpacs(fak["kapdetail"])
print(f"\nKAPDETAIL → idpac celkem: {len(idpacs)}")
idpac_to_rc = get_rodcis_for_idpacs(mdb, idpacs)
mdb.close()
medicus_rc = {
normalize_rc(rc)
for rc in idpac_to_rc.values()
if normalize_rc(rc)
}
print(f"Medicus (KAR.RODCIS): {len(medicus_rc)}")
# --- MySQL ---
mysql_rc = get_mysql_kapitace_rc(poj)
print(f"MySQL kapitace ZP: {len(mysql_rc)}")
# --- Porovnání ---
both = medicus_rc & mysql_rc
only_medicus = medicus_rc - mysql_rc
only_mysql = mysql_rc - medicus_rc
print("\n" + "=" * 80)
print(f"✅ V obou (OK): {len(both)}")
print(f"❌ Jen v Medicusu: {len(only_medicus)}")
print(f"❌ Jen v MySQL (kapitace): {len(only_mysql)}")
print("=" * 80)
if only_medicus:
print("\n❌ Jen v Medicusu (fakturováno, ale není v kapitaci ZP):")
for rc in sorted(only_medicus):
print(" ", rc)
if only_mysql:
print("\n❌ Jen v MySQL (v kapitaci ZP, ale není ve faktuře Medicusu):")
for rc in sorted(only_mysql):
print(" ", rc)
if __name__ == "__main__":
main()