d30404ffd0
- pacienti_gui.py: Tkinter aplikace se scrollovatelným seznamem pacientů ACTIVE v Medevio, kteří nejsou registrovaní v Medicusu; tlačítka VZP dotaz, Bod zlomu (binary search pojištění) a Označ neaktivní - _test_breakpoint.py: dočasný testovací skript pro binary search - NOTES.md: technická dokumentace adresáře Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""Dočasný test binary search pojištění pro jedno RC."""
|
||
|
||
import sys, time
|
||
sys.stdout.reconfigure(encoding="utf-8")
|
||
sys.stderr.reconfigure(encoding="utf-8")
|
||
from datetime import date, timedelta
|
||
from pathlib import Path
|
||
|
||
sys.path.insert(0, "U:/OrdinaceProjekt")
|
||
from Knihovny.vzpb2b_client import VZPB2BClient
|
||
|
||
CERT_PATH = Path("U:/OrdinaceProjekt/Insurance/Certificates/picka.pfx")
|
||
CERT_PASSWORD = "Vlado7309208104+"
|
||
ICZ = "09305000"
|
||
RC = "485221756"
|
||
DELAY = 1.50 # s
|
||
|
||
client = VZPB2BClient("prod", str(CERT_PATH), CERT_PASSWORD, icz=ICZ)
|
||
|
||
call_count = 0
|
||
|
||
def check(d: date) -> tuple[dict, bool]:
|
||
global call_count
|
||
call_count += 1
|
||
print(f" [{call_count:02d}] Testuji {d.isoformat()} ...", end=" ", flush=True)
|
||
for attempt in range(3):
|
||
try:
|
||
xml = client.stav_pojisteni(RC, k_datu=d.isoformat())
|
||
status = client.parse_stav_pojisteni(xml)
|
||
break
|
||
except Exception as e:
|
||
print(f"\n CHYBA (pokus {attempt+1}/3): {e} — čekám 3s ...", end=" ", flush=True)
|
||
time.sleep(3)
|
||
else:
|
||
print("SELHALO po 3 pokusech, končím.")
|
||
sys.exit(1)
|
||
stav = status.get("stav")
|
||
poj = status.get("kodPojistovny")
|
||
active = (status.get("stavVyrizeni") == 1 and stav == "1")
|
||
print(f"stav={stav!r:4s} pojišťovna={poj!r} aktivní={active}")
|
||
time.sleep(DELAY)
|
||
return status, active
|
||
|
||
today = date.today()
|
||
start_date = today - timedelta(days=730)
|
||
|
||
print("=" * 60)
|
||
print(f"RC: {RC}")
|
||
print(f"Okno: {start_date} -> {today}")
|
||
print("=" * 60)
|
||
|
||
print("\n[1] Kontrola krajů:")
|
||
status_start, active_start = check(start_date)
|
||
status_end, active_end = check(today)
|
||
|
||
print()
|
||
if not active_start:
|
||
print("✗ Na začátku (−2 roky) již stav != '1' — rozšiřte okno nebo jiná situace.")
|
||
sys.exit(0)
|
||
|
||
if active_end:
|
||
print("✗ Dnes stále stav '1' — v tomto okně zlom není.")
|
||
sys.exit(0)
|
||
|
||
print("✓ Levý okraj aktivní, pravý neaktivní → spouštím binary search.\n")
|
||
print("[2] Binary search:")
|
||
|
||
left, right = start_date, today
|
||
left_status, right_status = status_start, status_end
|
||
|
||
while (right - left).days > 1:
|
||
mid = left + timedelta(days=(right - left).days // 2)
|
||
mid_status, mid_active = check(mid)
|
||
if mid_active:
|
||
left, left_status = mid, mid_status
|
||
direction = "→ posunuji LEFT doprava"
|
||
else:
|
||
right, right_status = mid, mid_status
|
||
direction = "← posunuji RIGHT doleva"
|
||
print(f" {direction} (interval: {left} — {right}, {(right-left).days} dní)")
|
||
|
||
print()
|
||
print("=" * 60)
|
||
print("VÝSLEDEK:")
|
||
print(f" Poslední den pojištění (stav=1) : {left}")
|
||
print(f" pojišťovna: {left_status.get('nazevPojistovny')} / stav: {left_status.get('stav')}")
|
||
print(f" První den se změnou : {right}")
|
||
print(f" pojišťovna: {right_status.get('nazevPojistovny')} / stav: {right_status.get('stav')}")
|
||
print(f" Celkem API volání: {call_count}")
|
||
print("=" * 60)
|