266 lines
11 KiB
Python
266 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
batch_stav0_20250101.py
|
|
========================
|
|
Zpracuje 50 pacientů, kteří k 1. 1. 2025 vrátili stavVyrizeniPozadavku=0
|
|
na dotaz registrace lékaře (= VZP pojištěnce nenašla).
|
|
|
|
Pro každého:
|
|
1. Dotáže VZP stavPojisteni k 2025-01-01 → uloží do vzp_stav_pojisteni.
|
|
2. Pokud stav != '1' a != '4', binárně hledá zlom pojištění
|
|
a uloží do vzp_sledovani_pojisteni.
|
|
|
|
Resumovatelný — pacienty, kteří už mají záznam v vzp_stav_pojisteni
|
|
k 2025-01-01, přeskočí.
|
|
"""
|
|
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
from datetime import date, timedelta
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from Knihovny.mysql_db import connect_mysql
|
|
from Knihovny.vzpb2b_client import VZPB2BClient
|
|
|
|
# ── KONFIGURACE ───────────────────────────────────────────────────────────────
|
|
|
|
K_DATU = date(2025, 1, 1)
|
|
API_DELAY = 1.5
|
|
|
|
PFX_PATH = Path(__file__).resolve().parent.parent / "Certificates" / "picka.pfx"
|
|
PFX_PASSWORD = "Vlado7309208104+"
|
|
ICZ = "00000000"
|
|
DIC = "00000000"
|
|
ENV = "prod"
|
|
|
|
# ── PACIENTI ─────────────────────────────────────────────────────────────────
|
|
|
|
PACIENTI = [
|
|
("415513130", "Rohlíková", "Marie"),
|
|
("420622031", "Hamerník", "Josef"),
|
|
("430127082", "Anderle", "Václav"),
|
|
("435625017", "Kafková", "Marie"),
|
|
("436005111", "Plzáková", "Ivana"),
|
|
("445624103", "Kloučková", "Vlasta"),
|
|
("446116017", "Strnadová", "Dagmar"),
|
|
("456016085", "Kubcová", "Anna"),
|
|
("485627038", "Poustková", "Jiřina"),
|
|
("506109148", "Holubcová", "Svatava"),
|
|
("6008040247", "Šulc", "Jiří"),
|
|
("6054574130", "Přibová", "Darina"),
|
|
("6102694070", "Elouchefoun", "Aziz"),
|
|
("6654251978", "Svozilová", "Ivana"),
|
|
("6808292018", "Moudrý", "Jiří"),
|
|
("6853222079", "Milatová", "Martina"),
|
|
("6909154934", "Novák", "Petr"),
|
|
("7056764319", "Michlíková", "Anna"),
|
|
("7157734210", "Moudry Molloy", "Joanne"),
|
|
("7309300449", "Vojáček", "Aleš"),
|
|
("7410540709", "Torres blanco", "Jose maria"),
|
|
("7459303599", "Noháčová", "Kateřina"),
|
|
("7651090106", "Matějková", "Jana"),
|
|
("7803744597", "Barrell", "Peter"),
|
|
("7855080420", "Vondřičková", "Zuzana"),
|
|
("7908030427", "Smetana", "Libor"),
|
|
("7957312099", "Nimeřická", "Michaela"),
|
|
("7961794126", "Tomyshynets", "Halyna"),
|
|
("8005291404", "Hanzl", "František"),
|
|
("8156013041", "Maršíková", "Simona"),
|
|
("8157544241", "Jarošová", "Zuzana"),
|
|
("8203120299", "Otčenášek", "Vojtěch"),
|
|
("8253215223", "Slavíková", "Kateřina"),
|
|
("8301070558", "Kříž", "Michal"),
|
|
("8352210438", "Bartáková", "Jana"),
|
|
("8412175123", "Mičulka", "Jan"),
|
|
("8454664262", "Feoktistová", "Irina"),
|
|
("8462150147", "Říhová", "Markéta"),
|
|
("8503120417", "Šindelář", "Tomáš"),
|
|
("8552170517", "Slabá", "Gabriela"),
|
|
("8558150227", "Horáková", "Lucie"),
|
|
("8652034380", "Kopová", "Jana"),
|
|
("8754280403", "Jindrová", "Helena"),
|
|
("8755075153", "Babjáková", "Jana"),
|
|
("8910584023", "Pham Van", "Duy"),
|
|
("8953010330", "Špatná", "Markéta"),
|
|
("8956039037", "Slavíková", "Zuzana"),
|
|
("9002025956", "Banáš", "Martin"),
|
|
("9010262448", "Bečica", "Marek"),
|
|
("9811040305", "Sidej", "Natan"),
|
|
]
|
|
|
|
# ── INIT ──────────────────────────────────────────────────────────────────────
|
|
|
|
vzp = VZPB2BClient(ENV, str(PFX_PATH), PFX_PASSWORD, icz=ICZ, dic=DIC)
|
|
mysql = connect_mysql()
|
|
call_count = 0
|
|
today = date.today()
|
|
|
|
# ── HELPERS ───────────────────────────────────────────────────────────────────
|
|
|
|
def check_stav(rc: str, check_date: date) -> str:
|
|
global call_count
|
|
if call_count > 0:
|
|
time.sleep(API_DELAY)
|
|
call_count += 1
|
|
print(f" [{call_count}] {check_date.isoformat()} ...", end=" ", flush=True)
|
|
xml = vzp.stav_pojisteni(rc=rc, k_datu=check_date.isoformat())
|
|
stav = vzp.parse_stav_pojisteni(xml)["stav"]
|
|
print(f"stav = {stav!r}")
|
|
return stav
|
|
|
|
def uloz_stav(rc, prijmeni, jmeno, k_datu, stav):
|
|
xml = vzp.stav_pojisteni(rc=rc, k_datu=k_datu.isoformat())
|
|
with mysql.cursor() as cur:
|
|
cur.execute("""
|
|
INSERT INTO vzp_stav_pojisteni (rc, prijmeni, jmeno, k_datu, stav, response_xml)
|
|
VALUES (%s, %s, %s, %s, %s, %s)
|
|
ON DUPLICATE KEY UPDATE stav=VALUES(stav), response_xml=VALUES(response_xml)
|
|
""", (rc, prijmeni, jmeno, k_datu, stav, xml))
|
|
|
|
def najdi_zlom(rc: str, last_ok_mysql) -> tuple:
|
|
if last_ok_mysql:
|
|
low = last_ok_mysql
|
|
high = today
|
|
print(f" MySQL last stav='1': {low} → [{low} … {high}]")
|
|
else:
|
|
print(" MySQL: žádný stav='1' — hledám zpětně po rocích ...")
|
|
prev_probe = today
|
|
low = high = None
|
|
for n in range(1, 21):
|
|
y = today.year - n
|
|
try:
|
|
probe = date(y, today.month, today.day)
|
|
except ValueError:
|
|
probe = date(y, today.month, today.day - 1)
|
|
stav = check_stav(rc, probe)
|
|
if stav == "1":
|
|
low = probe
|
|
high = prev_probe
|
|
print(f" Nalezeno stav='1' k {low} → [{low} … {high}]")
|
|
break
|
|
prev_probe = probe
|
|
if low is None:
|
|
print(" NELZE: stav='1' nenalezen ani 20 let zpět.")
|
|
return None, None
|
|
|
|
stav_low = check_stav(rc, low)
|
|
stav_high = check_stav(rc, high)
|
|
|
|
if stav_low != "1":
|
|
print(f" NELZE: dolní mez {low} má stav='{stav_low}'.")
|
|
return None, None
|
|
if stav_high == "1":
|
|
print(f" INFO: horní mez {high} má stav='1' — aktuálně pojištěn.")
|
|
return None, None
|
|
|
|
print(f" Binární hledání ({(high - low).days} dní) ...")
|
|
while (high - low).days > 1:
|
|
mid = low + timedelta(days=(high - low).days // 2)
|
|
stav = check_stav(rc, mid)
|
|
if stav == "1":
|
|
low = mid
|
|
else:
|
|
high = mid
|
|
|
|
return low, high # insured_to, uninsured_from
|
|
|
|
# ── RESUME: načti již hotové ──────────────────────────────────────────────────
|
|
|
|
with mysql.cursor() as cur:
|
|
cur.execute("SELECT rc FROM vzp_stav_pojisteni WHERE k_datu = %s", (K_DATU,))
|
|
hotove = {row[0] for row in cur.fetchall()}
|
|
|
|
zbyvaji = [(rc, p, j) for rc, p, j in PACIENTI if rc not in hotove]
|
|
print(f"Celkem pacientů: {len(PACIENTI)}, již hotovo: {len(hotove)}, zbývá: {len(zbyvaji)}")
|
|
print(f"API prodleva: {API_DELAY}s | K_DATU: {K_DATU}\n")
|
|
print("=" * 60)
|
|
|
|
# ── HLAVNÍ SMYČKA ─────────────────────────────────────────────────────────────
|
|
|
|
vysledky = []
|
|
|
|
for i, (rc, prijmeni, jmeno) in enumerate(zbyvaji, 1):
|
|
print(f"\n[{i}/{len(zbyvaji)}] {prijmeni} {jmeno} (RC: {rc})")
|
|
|
|
# Krok 1: stav k K_DATU
|
|
if call_count > 0:
|
|
time.sleep(API_DELAY)
|
|
call_count += 1
|
|
print(f" [{call_count}] {K_DATU.isoformat()} ...", end=" ", flush=True)
|
|
xml_hist = vzp.stav_pojisteni(rc=rc, k_datu=K_DATU.isoformat())
|
|
stav_hist = vzp.parse_stav_pojisteni(xml_hist)["stav"]
|
|
print(f"stav = {stav_hist!r}")
|
|
|
|
with mysql.cursor() as cur:
|
|
cur.execute("""
|
|
INSERT INTO vzp_stav_pojisteni (rc, prijmeni, jmeno, k_datu, stav, response_xml)
|
|
VALUES (%s, %s, %s, %s, %s, %s)
|
|
ON DUPLICATE KEY UPDATE stav=VALUES(stav), response_xml=VALUES(response_xml)
|
|
""", (rc, prijmeni, jmeno, K_DATU, stav_hist, xml_hist))
|
|
|
|
# Krok 2: zlom (jen pokud stav != '1' a != '4')
|
|
insured_to = uninsured_from = None
|
|
|
|
if stav_hist in ("1", "4"):
|
|
print(f" → pojištěn (stav={stav_hist!r}), zlom se nehledá")
|
|
else:
|
|
# Zkontroluj watchlist
|
|
with mysql.cursor() as cur:
|
|
cur.execute("SELECT insured_to, uninsured_from FROM vzp_sledovani_pojisteni WHERE rc = %s", (rc,))
|
|
existuje = cur.fetchone()
|
|
|
|
if existuje:
|
|
insured_to, uninsured_from = existuje
|
|
print(f" → již ve watchlistu: insured_to={insured_to}, uninsured_from={uninsured_from}")
|
|
else:
|
|
with mysql.cursor() as cur:
|
|
cur.execute(
|
|
"SELECT MAX(k_datu) FROM vzp_stav_pojisteni WHERE rc = %s AND stav = '1'",
|
|
(rc,)
|
|
)
|
|
r = cur.fetchone()
|
|
last_ok = r[0] if r and r[0] else None
|
|
|
|
insured_to, uninsured_from = najdi_zlom(rc, last_ok)
|
|
|
|
with mysql.cursor() as cur:
|
|
cur.execute("""
|
|
INSERT INTO vzp_sledovani_pojisteni
|
|
(rc, prijmeni, jmeno, insured_to, uninsured_from,
|
|
aktualni_stav, prvni_detekce, posledni_kontrola)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
|
|
ON DUPLICATE KEY UPDATE
|
|
insured_to=VALUES(insured_to),
|
|
uninsured_from=VALUES(uninsured_from),
|
|
aktualni_stav=VALUES(aktualni_stav),
|
|
posledni_kontrola=VALUES(posledni_kontrola)
|
|
""", (rc, prijmeni, jmeno, insured_to, uninsured_from,
|
|
stav_hist, today, today))
|
|
|
|
vysledky.append({
|
|
"rc": rc, "prijmeni": prijmeni, "jmeno": jmeno,
|
|
"stav_20250101": stav_hist,
|
|
"insured_to": insured_to,
|
|
"uninsured_from": uninsured_from,
|
|
})
|
|
|
|
# ── SOUHRN ────────────────────────────────────────────────────────────────────
|
|
|
|
mysql.close()
|
|
|
|
print(f"\n{'=' * 60}")
|
|
print(f" SOUHRN — {len(vysledky)} zpracovaných pacientů")
|
|
print(f"{'=' * 60}")
|
|
print(f" {'Příjmení':<20} {'Jméno':<14} {'Stav':>5} {'Pojištěn do':<13} {'Nepoj. od'}")
|
|
print(f" {'-'*58}")
|
|
for v in vysledky:
|
|
ins = str(v["insured_to"]) if v["insured_to"] else "-"
|
|
uni = str(v["uninsured_from"]) if v["uninsured_from"] else "-"
|
|
print(f" {v['prijmeni']:<20} {v['jmeno']:<14} {v['stav_20250101']:>5} {ins:<13} {uni}")
|
|
|
|
print(f"\nCelkem VZP dotazů: {call_count}")
|