notebookvb
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
#!/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}")
|
||||
Reference in New Issue
Block a user