Fix agenda report and add MySQL sync for open requests
- 871 test.py: Switch auth from medevio_storage.json to token.txt, update MySQL port to 3306, add hyperlinks to Request_ID column, add better API error handling - sync_open_requests.py: New script to sync doneAt/removedAt/updatedAt from Medevio API to MySQL for requests incorrectly marked as open - check_request.py: Diagnostic script to inspect a single request via API - check_mysql.py: Diagnostic script to inspect a single request in MySQL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
178
40 agenda a požadavky/sync_open_requests.py
Normal file
178
40 agenda a požadavky/sync_open_requests.py
Normal file
@@ -0,0 +1,178 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Sync open requests: checks each request marked as open in MySQL (doneAt IS NULL
|
||||
AND removedAt IS NULL) against the Medevio API. If the API shows the request is
|
||||
closed (doneAt) or removed (removedAt), updates MySQL accordingly.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import time
|
||||
import requests
|
||||
import pymysql
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# ==============================
|
||||
# UTF-8 output (Windows friendly)
|
||||
# ==============================
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
sys.stderr.reconfigure(encoding="utf-8")
|
||||
except AttributeError:
|
||||
import io
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8")
|
||||
|
||||
# ==============================
|
||||
# DRY RUN - set to True to only print what would be updated, False to actually update
|
||||
# ==============================
|
||||
DRY_RUN = False
|
||||
|
||||
# ==============================
|
||||
# CONFIG
|
||||
# ==============================
|
||||
GRAPHQL_URL = "https://api.medevio.cz/graphql"
|
||||
CLINIC_SLUG = "mudr-buzalkova"
|
||||
|
||||
TOKEN_PATH = Path(__file__).parent / "token.txt"
|
||||
if not TOKEN_PATH.exists():
|
||||
raise SystemExit("❌ token.txt not found")
|
||||
|
||||
gateway_token = TOKEN_PATH.read_text(encoding="utf-8").strip()
|
||||
headers = {
|
||||
"content-type": "application/json",
|
||||
"authorization": f"Bearer {gateway_token}",
|
||||
"origin": "https://my.medevio.cz",
|
||||
"referer": "https://my.medevio.cz/",
|
||||
}
|
||||
|
||||
DB_CONFIG = {
|
||||
"host": "192.168.1.76",
|
||||
"port": 3306,
|
||||
"user": "root",
|
||||
"password": "Vlado9674+",
|
||||
"database": "medevio",
|
||||
"charset": "utf8mb4",
|
||||
"cursorclass": pymysql.cursors.DictCursor,
|
||||
}
|
||||
|
||||
GRAPHQL_QUERY = """
|
||||
query GetPatientRequest2($requestId: UUID!, $clinicSlug: String!) {
|
||||
request: getPatientRequest2(patientRequestId: $requestId, clinicSlug: $clinicSlug) {
|
||||
id
|
||||
doneAt
|
||||
removedAt
|
||||
updatedAt
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
def fix_datetime(dt_str):
|
||||
if not dt_str:
|
||||
return None
|
||||
try:
|
||||
return datetime.fromisoformat(dt_str.replace("Z", "+00:00"))
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def fetch_request(request_id):
|
||||
payload = {
|
||||
"operationName": "GetPatientRequest2",
|
||||
"query": GRAPHQL_QUERY,
|
||||
"variables": {
|
||||
"requestId": request_id,
|
||||
"clinicSlug": CLINIC_SLUG,
|
||||
},
|
||||
}
|
||||
for attempt in range(3):
|
||||
try:
|
||||
r = requests.post(GRAPHQL_URL, json=payload, headers=headers, timeout=30)
|
||||
break
|
||||
except (requests.ConnectionError, requests.Timeout, requests.exceptions.RequestException) as e:
|
||||
print(f" ⚠️ Attempt {attempt+1}/3 failed: {e}")
|
||||
time.sleep(2)
|
||||
else:
|
||||
print(f" ❌ Connection failed after 3 attempts for {request_id}")
|
||||
return None
|
||||
if r.status_code != 200:
|
||||
print(f" ❌ HTTP {r.status_code} for {request_id}")
|
||||
return None
|
||||
data = r.json()
|
||||
if "errors" in data:
|
||||
print(f" ❌ API error for {request_id}: {data['errors']}")
|
||||
return None
|
||||
return data.get("data", {}).get("request")
|
||||
|
||||
|
||||
# ==============================
|
||||
# MAIN
|
||||
# ==============================
|
||||
conn = pymysql.connect(**DB_CONFIG)
|
||||
|
||||
# 1) Read all open requests from MySQL
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id, displayTitle, pacient_prijmeni, pacient_jmeno "
|
||||
"FROM pozadavky WHERE doneAt IS NULL AND removedAt IS NULL"
|
||||
)
|
||||
open_requests = cur.fetchall()
|
||||
|
||||
mode = "DRY RUN" if DRY_RUN else "LIVE"
|
||||
print(f"🔧 Mode: {mode}")
|
||||
print(f"📋 Found {len(open_requests)} open requests in MySQL.\n")
|
||||
|
||||
updated = 0
|
||||
errors = 0
|
||||
|
||||
for i, req in enumerate(open_requests, 1):
|
||||
rid = req["id"]
|
||||
name = f"{req.get('pacient_prijmeni', '')} {req.get('pacient_jmeno', '')}".strip()
|
||||
title = req.get("displayTitle", "")
|
||||
print(f"[{i}/{len(open_requests)}] {name} – {title} ({rid})")
|
||||
|
||||
api_data = fetch_request(rid)
|
||||
if api_data is None:
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
api_done = api_data.get("doneAt")
|
||||
api_removed = api_data.get("removedAt")
|
||||
api_updated = api_data.get("updatedAt")
|
||||
|
||||
if api_done or api_removed:
|
||||
done_dt = fix_datetime(api_done)
|
||||
removed_dt = fix_datetime(api_removed)
|
||||
updated_dt = fix_datetime(api_updated)
|
||||
|
||||
status = "DONE" if api_done else "REMOVED"
|
||||
|
||||
if DRY_RUN:
|
||||
print(f" 🔍 Would update → {status} (doneAt={api_done}, removedAt={api_removed})")
|
||||
else:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"UPDATE pozadavky SET doneAt = %s, removedAt = %s, updatedAt = %s WHERE id = %s",
|
||||
(done_dt, removed_dt, updated_dt, rid),
|
||||
)
|
||||
conn.commit()
|
||||
print(f" ✅ Updated → {status}")
|
||||
|
||||
updated += 1
|
||||
else:
|
||||
print(f" ⏳ Still open")
|
||||
|
||||
# Be gentle with the API
|
||||
time.sleep(1)
|
||||
|
||||
conn.close()
|
||||
|
||||
print(f"\n{'='*50}")
|
||||
print(f"📊 Total open in MySQL: {len(open_requests)}")
|
||||
print(f"✅ Updated (closed/removed): {updated}")
|
||||
print(f"⏳ Still open: {len(open_requests) - updated - errors}")
|
||||
print(f"❌ Errors: {errors}")
|
||||
Reference in New Issue
Block a user