#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ VZP – zjištění od kdy platí AKTUÁLNÍ STAV pojištění (stav) --------------------------------------------------------- - vstup: rodné číslo - porovnává pouze položku: res["stav"] - hledá změnu: roky → měsíce → týdny → dny - 1 request / sekunda (tvrdý limit) - ukládá vše do MySQL (audit) """ import sys import time import logging from pathlib import Path from datetime import date, timedelta import pymysql # ========================================== # PROJECT ROOT # ========================================== PROJECT_ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(PROJECT_ROOT)) from knihovny.vzpb2b_client import VZPB2BClient # ========================================== # LOGGING # ========================================== logging.basicConfig( filename="insurance_status_history.log", level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", encoding="utf-8" ) console = logging.getLogger("console") console.setLevel(logging.INFO) handler = logging.StreamHandler() handler.setFormatter(logging.Formatter("%(message)s")) console.addHandler(handler) def log(msg): logging.info(msg) console.info(msg) def log_err(msg): logging.error(msg) console.error(msg) # ========================================== # MYSQL # ========================================== mysql = pymysql.connect( host="192.168.1.76", port=3307, user="root", password="Vlado9674+", database="medevio", charset="utf8mb4", autocommit=True ) def save_result(rc, prijmeni, jmeno, k_datu, res, xml): sql = """ INSERT INTO vzp_stav_pojisteni (rc, prijmeni, jmeno, k_datu, stav, kod_pojistovny, nazev_pojistovny, pojisteni_kod, stav_vyrizeni, response_xml) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) """ with mysql.cursor() as cur: cur.execute(sql, ( rc, prijmeni, jmeno, k_datu, res["stav"], res["kodPojistovny"], res["nazevPojistovny"], res["pojisteniKod"], res["stavVyrizeni"], xml )) # ========================================== # RATE LIMITER – 1 req / sec # ========================================== _LAST_CALL = 0.0 def vzp_call(func, *args, **kwargs): global _LAST_CALL now = time.time() delta = now - _LAST_CALL if delta < 1.1: time.sleep(1.1 - delta) result = func(*args, **kwargs) _LAST_CALL = time.time() return result # ========================================== # CONFIG # ========================================== PFX_PATH = PROJECT_ROOT / "certificates" / "picka.pfx" PFX_PASSWORD = "Vlado7309208104+" ENV = "prod" ICZ = "00000000" DIC = "00000000" if not PFX_PATH.exists(): raise FileNotFoundError(f"PFX not found: {PFX_PATH}") # ========================================== # INIT VZP CLIENT # ========================================== vzp = VZPB2BClient( ENV, str(PFX_PATH), PFX_PASSWORD, icz=ICZ, dic=DIC ) # ========================================== # INPUT # ========================================== rc = input("Zadej rodné číslo (bez /): ").strip() # jméno jen informativně (pokud existuje historie) with mysql.cursor(pymysql.cursors.DictCursor) as cur: cur.execute(""" SELECT prijmeni, jmeno FROM vzp_stav_pojisteni WHERE rc = %s ORDER BY k_datu DESC LIMIT 1 """, (rc,)) row = cur.fetchone() prijmeni = row["prijmeni"] if row else "?" jmeno = row["jmeno"] if row else "?" today = date.today() log(f"▶ Kontrola STAVU pojištění: {prijmeni} {jmeno} ({rc})") # ========================================== # CHECK FUNCTION (STAV) # ========================================== def check_at(d: date): xml = vzp_call( vzp.stav_pojisteni, rc=rc, k_datu=d.isoformat() ) res = vzp.parse_stav_pojisteni(xml) stav = res["stav"] log(f" test {d.isoformat()} → stav={stav}") save_result(rc, prijmeni, jmeno, d, res, xml) return stav # ========================================== # CURRENT STAV # ========================================== today_stav = check_at(today) log(f"✔ Aktuální stav: {today_stav}") # ========================================== # 1️⃣ BACKWARD – YEARS # ========================================== probe = today last_same = today while True: probe -= timedelta(days=365) if probe.year < today.year - 20: break if check_at(probe) != today_stav: break last_same = probe # ========================================== # 2️⃣ FORWARD – MONTHS # ========================================== probe = probe while True: probe += timedelta(days=30) if probe >= last_same: break if check_at(probe) == today_stav: upper = probe lower = probe - timedelta(days=30) break # ========================================== # 3️⃣ FORWARD – WEEKS # ========================================== probe = lower while True: probe += timedelta(days=7) if probe >= upper: break if check_at(probe) == today_stav: upper = probe lower = probe - timedelta(days=7) break # ========================================== # 4️⃣ FORWARD – DAYS # ========================================== probe = lower while True: probe += timedelta(days=1) if check_at(probe) == today_stav: change_date = probe break # ========================================== # RESULT # ========================================== log("\n✅ VÝSLEDEK") log(f"Stav '{today_stav}' platí od: {change_date.isoformat()}") mysql.close() log("\nDONE.")