235 lines
5.8 KiB
Python
235 lines
5.8 KiB
Python
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()
|