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: =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()