notebookVB
This commit is contained in:
234
05 Kontrola pojištěnců/30 Porovnani kapitace.py
Normal file
234
05 Kontrola pojištěnců/30 Porovnani kapitace.py
Normal 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()
|
||||
Reference in New Issue
Block a user