notebookvb
This commit is contained in:
@@ -0,0 +1,385 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Cteni agendy z Medevio kalendare.
|
||||
|
||||
Hlavni funkce: `list_agendu(start, end=None, calendar=None)`
|
||||
start date | datetime | str 'YYYY-MM-DD' nebo 'YYYY-MM-DD HH:MM'
|
||||
end to stejne; pokud None, bere se konec dne `start` (23:59:59)
|
||||
calendar None = oba (vlado + manzelka), nebo "vlado" / "manzelka" / UUID,
|
||||
nebo list techto hodnot
|
||||
|
||||
Vraci list dictu serazenych podle start. Kazdy dict obsahuje pole `calendar`
|
||||
(jmeno) navic.
|
||||
|
||||
CLI:
|
||||
python agenda_dne.py # interaktivne se zepta
|
||||
python agenda_dne.py --od 2026-06-03 --do 2026-06-03 --kalendar vlado
|
||||
python agenda_dne.py --od 2026-06-01 --do 2026-06-07 # tyden, oba
|
||||
python agenda_dne.py --den 2026-06-03 # zkratka pro jeden den
|
||||
python agenda_dne.py --den dnes
|
||||
python agenda_dne.py --den +1 --kalendar manzelka
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from datetime import datetime, date, timedelta
|
||||
|
||||
import requests
|
||||
from dateutil import parser as dtparser, tz
|
||||
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
GRAPHQL_URL = "https://api.medevio.cz/graphql"
|
||||
CLINIC_SLUG = "mudr-buzalkova"
|
||||
PRAGUE_TZ = tz.gettz("Europe/Prague")
|
||||
|
||||
# Pojmenovane kalendare - viz pamet project-medevio-kalendar
|
||||
CALENDARS = {
|
||||
"vlado": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"manzelka": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
}
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
TOKEN_PATH = BASE_DIR / "token.txt"
|
||||
DEBUG_DIR = BASE_DIR / "debug"
|
||||
|
||||
QUERY = """query Agenda_ListAll(
|
||||
$calendarIds: [UUID!]!, $clinicSlug: String!,
|
||||
$locale: Locale!, $since: DateTime!, $until: DateTime!
|
||||
) {
|
||||
reservations: listClinicReservations(
|
||||
clinicSlug: $clinicSlug, calendarIds: $calendarIds,
|
||||
since: $since, until: $until
|
||||
) {
|
||||
id start end note done color canceledAt calendarId
|
||||
request {
|
||||
id displayTitle(locale: $locale)
|
||||
extendedPatient {
|
||||
id name surname dob phone identificationNumber
|
||||
insuranceCompanyObject { code shortName }
|
||||
}
|
||||
}
|
||||
}
|
||||
recurringReservations: listClinicRecurringReservations(
|
||||
clinicSlug: $clinicSlug, calendarIds: $calendarIds,
|
||||
since: $since, until: $until
|
||||
) {
|
||||
recurringReservation {
|
||||
id calendarId color note
|
||||
rrule { frequency interval dtstart tzid byweekday bymonthday byweekno }
|
||||
}
|
||||
instances { start end note color }
|
||||
}
|
||||
}"""
|
||||
|
||||
|
||||
# ==================== Helpery ====================
|
||||
|
||||
def _load_token() -> str:
|
||||
token = TOKEN_PATH.read_text(encoding="utf-8").strip()
|
||||
if token.startswith("Bearer "):
|
||||
token = token.split(" ", 1)[1]
|
||||
return token
|
||||
|
||||
|
||||
def _headers() -> dict:
|
||||
return {
|
||||
"content-type": "application/json",
|
||||
"authorization": f"Bearer {_load_token()}",
|
||||
"origin": "https://my.medevio.cz",
|
||||
"referer": "https://my.medevio.cz/",
|
||||
}
|
||||
|
||||
|
||||
def _is_uuid(s: str) -> bool:
|
||||
return isinstance(s, str) and len(s) == 36 and s.count("-") == 4
|
||||
|
||||
|
||||
def _resolve_calendars(calendar) -> list[tuple[str, str]]:
|
||||
"""Vraci list (jmeno, uuid). None = oba pojmenovane."""
|
||||
if calendar is None:
|
||||
return list(CALENDARS.items())
|
||||
items = calendar if isinstance(calendar, list) else [calendar]
|
||||
out = []
|
||||
for c in items:
|
||||
if c in CALENDARS:
|
||||
out.append((c, CALENDARS[c]))
|
||||
elif _is_uuid(c):
|
||||
# zkusime najit jmeno
|
||||
name = next((n for n, u in CALENDARS.items() if u == c), c)
|
||||
out.append((name, c))
|
||||
else:
|
||||
raise ValueError(f"Neznamy kalendar: {c!r}")
|
||||
return out
|
||||
|
||||
|
||||
def _to_dt(value, end_of_day: bool = False) -> datetime:
|
||||
"""Prevede date/datetime/str na datetime s Europe/Prague timezone."""
|
||||
if isinstance(value, datetime):
|
||||
dt = value
|
||||
elif isinstance(value, date):
|
||||
dt = datetime.combine(
|
||||
value,
|
||||
datetime.max.time().replace(microsecond=0) if end_of_day else datetime.min.time(),
|
||||
)
|
||||
elif isinstance(value, str):
|
||||
s = value.strip().replace("T", " ")
|
||||
if " " in s:
|
||||
dt = datetime.strptime(s, "%Y-%m-%d %H:%M")
|
||||
else:
|
||||
d = datetime.strptime(s, "%Y-%m-%d").date()
|
||||
dt = datetime.combine(
|
||||
d,
|
||||
datetime.max.time().replace(microsecond=0) if end_of_day else datetime.min.time(),
|
||||
)
|
||||
else:
|
||||
raise TypeError(f"Nelze prevest na datetime: {value!r}")
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=PRAGUE_TZ)
|
||||
return dt
|
||||
|
||||
|
||||
def _to_utc_iso(dt: datetime) -> str:
|
||||
return dt.astimezone(tz.UTC).strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
||||
|
||||
|
||||
# ==================== Hlavni funkce ====================
|
||||
|
||||
def list_agendu(
|
||||
start,
|
||||
end=None,
|
||||
calendar=None,
|
||||
save_debug: bool = True,
|
||||
) -> list[dict]:
|
||||
"""Vraci rezervace v zadanem rozmezi pro vybrane kalendare.
|
||||
|
||||
Pokud `end` neni zadan, pouzije se konec stejneho dne jako `start`.
|
||||
Pokud `calendar` je None, vrati se oba pojmenovane kalendare slouceny.
|
||||
"""
|
||||
start_dt = _to_dt(start, end_of_day=False)
|
||||
if end is None:
|
||||
end_dt = _to_dt(start_dt.date(), end_of_day=True)
|
||||
else:
|
||||
end_dt = _to_dt(end, end_of_day=True)
|
||||
|
||||
cals = _resolve_calendars(calendar)
|
||||
|
||||
payload = {
|
||||
"operationName": "Agenda_ListAll",
|
||||
"variables": {
|
||||
"calendarIds": [uuid for _, uuid in cals],
|
||||
"clinicSlug": CLINIC_SLUG,
|
||||
"since": _to_utc_iso(start_dt),
|
||||
"until": _to_utc_iso(end_dt),
|
||||
"locale": "cs",
|
||||
},
|
||||
"query": QUERY,
|
||||
}
|
||||
|
||||
r = requests.post(GRAPHQL_URL, headers=_headers(), data=json.dumps(payload), timeout=30)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
|
||||
if save_debug:
|
||||
DEBUG_DIR.mkdir(exist_ok=True)
|
||||
debug_path = DEBUG_DIR / f"agenda_{start_dt:%Y%m%d}_{end_dt:%Y%m%d}_{datetime.now():%H%M%S}.json"
|
||||
debug_path.write_text(
|
||||
json.dumps({"request": payload["variables"], "response": data}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"[debug] {debug_path}")
|
||||
|
||||
if "errors" in data:
|
||||
raise RuntimeError(f"GraphQL error: {data['errors']}")
|
||||
|
||||
uuid_to_name = {uuid: name for name, uuid in cals}
|
||||
parsed = []
|
||||
|
||||
# 1) Jednorazove rezervace
|
||||
for res in data["data"].get("reservations") or []:
|
||||
if res.get("canceledAt"):
|
||||
continue
|
||||
s = dtparser.isoparse(res["start"]).astimezone(PRAGUE_TZ)
|
||||
e = dtparser.isoparse(res["end"]).astimezone(PRAGUE_TZ)
|
||||
req = res.get("request") or {}
|
||||
pat = req.get("extendedPatient") or {}
|
||||
ins = pat.get("insuranceCompanyObject") or {}
|
||||
request_id = req.get("id") or ""
|
||||
parsed.append({
|
||||
"typ": "pacient" if request_id else "poznamka",
|
||||
"calendar": uuid_to_name.get(res.get("calendarId"), res.get("calendarId")),
|
||||
"calendar_id": res.get("calendarId"),
|
||||
"start": s,
|
||||
"end": e,
|
||||
"title": req.get("displayTitle") or "",
|
||||
"patient": f"{pat.get('surname','')} {pat.get('name','')}".strip(),
|
||||
"dob": pat.get("dob") or "",
|
||||
"rc": pat.get("identificationNumber") or "",
|
||||
"phone": pat.get("phone") or "",
|
||||
"insurance": ins.get("shortName") or "",
|
||||
"insurance_code": ins.get("code") or "",
|
||||
"note": (res.get("note") or "").strip(),
|
||||
"done": bool(res.get("done")),
|
||||
"color": res.get("color") or "",
|
||||
"reservation_id": res["id"],
|
||||
"request_id": request_id,
|
||||
"patient_id": pat.get("id") or "",
|
||||
"recurring": False,
|
||||
})
|
||||
|
||||
# 2) Opakujici se - jednotlive instance v intervalu
|
||||
for rr in data["data"].get("recurringReservations") or []:
|
||||
rule = rr.get("recurringReservation") or {}
|
||||
cal_id = rule.get("calendarId")
|
||||
for inst in rr.get("instances") or []:
|
||||
s = dtparser.isoparse(inst["start"]).astimezone(PRAGUE_TZ)
|
||||
e = dtparser.isoparse(inst["end"]).astimezone(PRAGUE_TZ)
|
||||
parsed.append({
|
||||
"typ": "poznamka", # opakujici se vznikaji vzdy pres "Jina udalost"
|
||||
"calendar": uuid_to_name.get(cal_id, cal_id),
|
||||
"calendar_id": cal_id,
|
||||
"start": s,
|
||||
"end": e,
|
||||
"title": "",
|
||||
"patient": "",
|
||||
"dob": "", "rc": "", "phone": "",
|
||||
"insurance": "", "insurance_code": "",
|
||||
"note": (inst.get("note") or rule.get("note") or "").strip(),
|
||||
"done": False,
|
||||
"color": inst.get("color") or rule.get("color") or "",
|
||||
"reservation_id": rule.get("id"),
|
||||
"request_id": "",
|
||||
"patient_id": "",
|
||||
"recurring": True,
|
||||
"rrule": rule.get("rrule"),
|
||||
})
|
||||
|
||||
parsed.sort(key=lambda x: (x["start"], x["calendar"]))
|
||||
return parsed
|
||||
|
||||
|
||||
# Zachovani zpetne kompatibility
|
||||
def get_agenda(day, calendar=None) -> list[dict]:
|
||||
"""Vraci agendu jednoho dne. Pro zpetnou kompat se starsim API."""
|
||||
return list_agendu(day, end=day, calendar=calendar)
|
||||
|
||||
|
||||
# ==================== Vystup ====================
|
||||
|
||||
def print_agenda(reservations: list[dict], header: str | None = None) -> None:
|
||||
cz_dny = ["pondeli", "utery", "streda", "ctvrtek", "patek", "sobota", "nedele"]
|
||||
|
||||
if header is None:
|
||||
if reservations:
|
||||
dates = sorted({r["start"].date() for r in reservations})
|
||||
if len(dates) == 1:
|
||||
header = f"Agenda {dates[0].isoformat()} ({cz_dny[dates[0].weekday()]})"
|
||||
else:
|
||||
header = f"Agenda {dates[0].isoformat()} - {dates[-1].isoformat()}"
|
||||
else:
|
||||
header = "Agenda"
|
||||
|
||||
print(header)
|
||||
print("=" * len(header))
|
||||
|
||||
if not reservations:
|
||||
print("(zadne rezervace)")
|
||||
return
|
||||
|
||||
last_date = None
|
||||
for r in reservations:
|
||||
if r["start"].date() != last_date:
|
||||
if last_date is not None:
|
||||
print()
|
||||
print(f"--- {r['start'].date().isoformat()} ({cz_dny[r['start'].weekday()]}) ---")
|
||||
last_date = r["start"].date()
|
||||
|
||||
time_str = f"{r['start']:%H:%M}-{r['end']:%H:%M}"
|
||||
cal = f"[{r['calendar']}]" if r["calendar"] else ""
|
||||
typ = f"<{r.get('typ','?')}>"
|
||||
flags = []
|
||||
if r["done"]:
|
||||
flags.append("HOTOVO")
|
||||
if r.get("recurring"):
|
||||
flags.append("OPAKOVANE")
|
||||
flag_str = f" [{', '.join(flags)}]" if flags else ""
|
||||
|
||||
label = r["patient"] if r.get("typ") == "pacient" else (r.get("note") or "(bez popisu)")
|
||||
line = f"{time_str} {cal} {typ} {label}"
|
||||
if r["dob"]:
|
||||
line += f" *{r['dob']}"
|
||||
if r["insurance"]:
|
||||
line += f" {r['insurance']}"
|
||||
line += flag_str
|
||||
print(line)
|
||||
if r["title"]:
|
||||
print(f" {r['title']}")
|
||||
if r["note"]:
|
||||
for ln in r["note"].splitlines():
|
||||
print(f" poznamka: {ln}")
|
||||
|
||||
print()
|
||||
print(f"Celkem: {len(reservations)} rezervaci")
|
||||
|
||||
|
||||
# ==================== CLI ====================
|
||||
|
||||
def _parse_day_arg(arg: str | None) -> date:
|
||||
if not arg or arg in ("dnes", "today"):
|
||||
return date.today()
|
||||
if arg in ("zitra", "tomorrow"):
|
||||
return date.today() + timedelta(days=1)
|
||||
if arg in ("vcera", "yesterday"):
|
||||
return date.today() - timedelta(days=1)
|
||||
if arg.startswith(("+", "-")) and arg[1:].isdigit():
|
||||
return date.today() + timedelta(days=int(arg))
|
||||
return datetime.strptime(arg, "%Y-%m-%d").date()
|
||||
|
||||
|
||||
def _prompt_interactive() -> tuple[date, date, str | None]:
|
||||
cz_dny = ["pondeli", "utery", "streda", "ctvrtek", "patek", "sobota", "nedele"]
|
||||
today = date.today()
|
||||
print("Cteni agendy z Medevio")
|
||||
print(f"Dnes je {today.isoformat()} ({cz_dny[today.weekday()]})")
|
||||
print()
|
||||
print("Od (YYYY-MM-DD / +N / -N / dnes / zitra / vcera, Enter = dnes):")
|
||||
od = _parse_day_arg(input("> ").strip() or None)
|
||||
print(f"Do (Enter = stejny den jako od = {od.isoformat()}):")
|
||||
do_raw = input("> ").strip()
|
||||
do = _parse_day_arg(do_raw) if do_raw else od
|
||||
print(f"Kalendar (vlado / manzelka / Enter = oba):")
|
||||
cal = input("> ").strip() or None
|
||||
return od, do, cal
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Cteni agendy z Medevio.")
|
||||
ap.add_argument("--od", help="Pocatecni datum 'YYYY-MM-DD' / +N / -N / dnes/zitra/vcera")
|
||||
ap.add_argument("--do", dest="do_", help="Koncove datum (default = stejny jako --od)")
|
||||
ap.add_argument("--den", help="Zkratka: --od i --do nastaveny na tento den")
|
||||
ap.add_argument("--kalendar", default=None,
|
||||
help=f"{'/'.join(CALENDARS)} nebo UUID. Bez parametru = oba.")
|
||||
args = ap.parse_args()
|
||||
|
||||
if args.den:
|
||||
od = do = _parse_day_arg(args.den)
|
||||
cal = args.kalendar
|
||||
elif args.od:
|
||||
od = _parse_day_arg(args.od)
|
||||
do = _parse_day_arg(args.do_) if args.do_ else od
|
||||
cal = args.kalendar
|
||||
else:
|
||||
od, do, cal = _prompt_interactive()
|
||||
|
||||
reservations = list_agendu(od, do, calendar=cal)
|
||||
print_agenda(reservations)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,178 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"144c4e12-347c-49ca-9ec0-8ca965a4470d"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-28T22:00:00.000Z",
|
||||
"until": "2026-05-29T22:00:00.000Z",
|
||||
"locale": "cs",
|
||||
"emptyCalendarIds": false
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "6e02c736-6060-41bb-90f5-a9dcd309bee4",
|
||||
"start": "2026-05-29T09:40:00.000Z",
|
||||
"end": "2026-05-29T09:50:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "98b890a9-bc2b-42c8-859f-fe109f09e1f6",
|
||||
"displayTitle": "Očkování - Černý kašel (kombinovaná vakcína Adacel [černý kašel, tetanus, záškrt])",
|
||||
"extendedPatient": {
|
||||
"id": "92e7be7e-e41b-4181-afc3-624a82bd94f2",
|
||||
"name": "Nicol",
|
||||
"surname": "Slaninová",
|
||||
"dob": "1978-12-20",
|
||||
"phone": "+420777145986",
|
||||
"identificationNumber": "7862202920",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "e47d9c64-b84e-4a89-bb3e-77e96db55e84",
|
||||
"start": "2026-05-29T08:45:00.000Z",
|
||||
"end": "2026-05-29T09:30:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "9154f33e-6724-450c-af58-3abd0a4778da",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "17a5563e-4044-4c67-b9fd-928be546ea5a",
|
||||
"name": "Martin",
|
||||
"surname": "Štoček",
|
||||
"dob": "1989-10-19",
|
||||
"phone": "+420604131463",
|
||||
"identificationNumber": "8910193336",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "8f0a84e9-1f88-4f94-b826-7364095284fc",
|
||||
"start": "2026-05-29T10:00:00.000Z",
|
||||
"end": "2026-05-29T10:05:00.000Z",
|
||||
"note": "ukončit PN Pelcová E.",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "565cf3f0-ad44-485f-9433-18e271f429c1",
|
||||
"start": "2026-05-29T09:30:00.000Z",
|
||||
"end": "2026-05-29T09:50:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "4ae28457-ee0c-46f0-89b1-23075cfcbe81",
|
||||
"displayTitle": "Konzultace zdravotního stavu ",
|
||||
"extendedPatient": {
|
||||
"id": "88a2c4f3-ad3e-472b-899c-c86b72d6f2e7",
|
||||
"name": "Hana",
|
||||
"surname": "Hlavsová",
|
||||
"dob": "1941-09-06",
|
||||
"phone": null,
|
||||
"identificationNumber": "415906003",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c87c1cfe-2360-478c-8820-a9d92a47511e",
|
||||
"start": "2026-05-29T09:50:00.000Z",
|
||||
"end": "2026-05-29T10:00:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "0067cd89-ccb0-4b23-9548-260e2efd2d45",
|
||||
"displayTitle": "Odběry",
|
||||
"extendedPatient": {
|
||||
"id": "fbb78b75-1c61-4915-8d06-1d7ceb6f9450",
|
||||
"name": "Petra",
|
||||
"surname": "Zelenková",
|
||||
"dob": "1983-01-11",
|
||||
"phone": "+420731585469",
|
||||
"identificationNumber": "8351112693",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9b3ab4a3-47aa-4438-9dd7-5289d74a16a5",
|
||||
"start": "2026-05-29T07:30:00.000Z",
|
||||
"end": "2026-05-29T08:00:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "c2dd4666-4be3-4543-ad02-bafb05694bd3",
|
||||
"displayTitle": "Předoperační vyšetření",
|
||||
"extendedPatient": {
|
||||
"id": "e6d965dd-b1ba-44c6-a0ba-915a83d45770",
|
||||
"name": "Markéta",
|
||||
"surname": "Bečicová",
|
||||
"dob": "1967-08-12",
|
||||
"phone": "+420736540111",
|
||||
"identificationNumber": "6758120446",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 205,
|
||||
"shortName": "ČPZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "86a379f8-3479-4c5e-86b8-550afc55491f",
|
||||
"start": "2026-05-29T08:00:00.000Z",
|
||||
"end": "2026-05-29T08:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "97e97780-1b9d-4c4d-be99-f05b25cad2fa",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "a72e32cb-752e-4b3b-bcce-fca9f142c76a",
|
||||
"name": "Eva",
|
||||
"surname": "Zemanová",
|
||||
"dob": "1939-09-12",
|
||||
"phone": "+420739555303",
|
||||
"identificationNumber": "395912079",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"144c4e12-347c-49ca-9ec0-8ca965a4470d"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-06-02T22:00:00.000Z",
|
||||
"until": "2026-06-03T22:00:00.000Z",
|
||||
"locale": "cs",
|
||||
"emptyCalendarIds": false
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "bc275236-970f-4b88-887e-b4c5f286e3a9",
|
||||
"start": "2026-06-03T08:00:00.000Z",
|
||||
"end": "2026-06-03T08:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "bebb68b3-f9e1-48e0-9e14-b72e5781b4c4",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "86931ca3-cfd4-4aed-af66-244cecc691ee",
|
||||
"name": "Sylvie",
|
||||
"surname": "Rejfířová",
|
||||
"dob": "1980-06-01",
|
||||
"phone": "+420602266614",
|
||||
"identificationNumber": "8056010149",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "73844dfa-316f-47da-ac3d-2554ff5aec7f",
|
||||
"start": "2026-06-03T08:45:00.000Z",
|
||||
"end": "2026-06-03T09:00:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "97dd7ace-1668-479b-a09b-44d775e53227",
|
||||
"displayTitle": "Kontrola INR (Quick)",
|
||||
"extendedPatient": {
|
||||
"id": "d8c2f2b6-fdf7-462e-91de-fce908aaf3de",
|
||||
"name": "Jaroslav",
|
||||
"surname": "Kameník",
|
||||
"dob": "1940-05-10",
|
||||
"phone": "+420776702345",
|
||||
"identificationNumber": "400510088",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c2c96faa-4129-4815-a213-ffdd887d42f8",
|
||||
"start": "2026-06-03T07:00:00.000Z",
|
||||
"end": "2026-06-03T07:30:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "4ee1cee1-5ccd-425d-85b1-3896d850a784",
|
||||
"displayTitle": "Prohlídka při léčbě cukrovky",
|
||||
"extendedPatient": {
|
||||
"id": "0aeefc63-8599-4602-b731-b7c81e9106a2",
|
||||
"name": "Miloslav",
|
||||
"surname": "Hájek",
|
||||
"dob": "1974-10-24",
|
||||
"phone": "+420602262242",
|
||||
"identificationNumber": "7410241014",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "906ca466-eb83-4a65-bc2e-90020714d4e9",
|
||||
"start": "2026-06-03T09:00:00.000Z",
|
||||
"end": "2026-06-03T09:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "6790af69-4416-4ef8-9101-7e3f7d668320",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "7bcf8cea-efe7-4f90-8e91-c8f88ba72ee6",
|
||||
"name": "Denisa",
|
||||
"surname": "Ryšavá",
|
||||
"dob": "2007-10-24",
|
||||
"phone": "+420606815415",
|
||||
"identificationNumber": "0760245079",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a91481ba-cf7c-4968-bd54-8424565cae3d",
|
||||
"start": "2026-06-03T09:45:00.000Z",
|
||||
"end": "2026-06-03T09:55:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "c0ac9fdb-5a82-4306-9d1c-ed22110205fe",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "ec4db98b-cce8-473c-a47e-ef24bf61d3d8",
|
||||
"name": "Romana",
|
||||
"surname": "Ratkiewiczová",
|
||||
"dob": "1990-04-15",
|
||||
"phone": "+420737261867",
|
||||
"identificationNumber": "9054151128",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b5f01f0c-0c9f-42bb-a7bd-f0a725638d38",
|
||||
"start": "2026-06-03T10:00:00.000Z",
|
||||
"end": "2026-06-03T10:10:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "48d490fa-0fd1-4a16-aba8-79f275043345",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "d8d36c4d-19fc-4405-9bf9-f9a733fb2dad",
|
||||
"name": "Jana",
|
||||
"surname": "Ptáčková",
|
||||
"dob": "1947-09-17",
|
||||
"phone": "+420604363791",
|
||||
"identificationNumber": "475917011",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "44d6f66b-95b9-4bfb-b2c9-69338a7cae8f",
|
||||
"start": "2026-06-03T10:10:00.000Z",
|
||||
"end": "2026-06-03T10:20:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "30e1d256-eaaf-4a0b-aa13-cd511e4e309e",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "bb27b85a-8703-4768-86f4-2cbf4c196dd1",
|
||||
"name": "Karel",
|
||||
"surname": "Galus",
|
||||
"dob": "1946-06-14",
|
||||
"phone": "+420605230820",
|
||||
"identificationNumber": "460614110",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 211,
|
||||
"shortName": "ZPMV"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b128a573-849d-4bf2-9317-01142147e61e",
|
||||
"start": "2026-06-03T10:30:00.000Z",
|
||||
"end": "2026-06-03T10:50:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "bbd0e36a-5148-43d2-8095-fcf746586778",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "5a0a9ff0-bbe8-4fc7-a27d-b7b475ee2189",
|
||||
"name": "Lenka",
|
||||
"surname": "Balousova",
|
||||
"dob": "1972-03-28",
|
||||
"phone": "+420603560064",
|
||||
"identificationNumber": "7253282355",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c0bbc7bc-2491-4143-a6b9-59d4fab9df63",
|
||||
"start": "2026-06-03T10:50:00.000Z",
|
||||
"end": "2026-06-03T11:05:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "b0f01a56-6ae6-47fa-94bf-e693977e127b",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "3e1090b7-d0c2-4dd8-bbfe-dc464d2f1671",
|
||||
"name": "Lenka",
|
||||
"surname": "Vaněčková",
|
||||
"dob": "1943-03-17",
|
||||
"phone": "+420776599498",
|
||||
"identificationNumber": "435317067",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9d2f969b-da52-418c-8465-d29021beab49",
|
||||
"start": "2026-06-03T11:15:00.000Z",
|
||||
"end": "2026-06-03T11:25:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"request": {
|
||||
"id": "019ec07d-b454-4231-9b49-9389fe675faa",
|
||||
"displayTitle": "Očkování - Klíšťová encefalitida",
|
||||
"extendedPatient": {
|
||||
"id": "865e0404-b2c8-4635-8d8d-df7a14275b14",
|
||||
"name": "Jiří",
|
||||
"surname": "Chomát",
|
||||
"dob": "1938-03-14",
|
||||
"phone": "+420737217617",
|
||||
"identificationNumber": "380314026",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"144c4e12-347c-49ca-9ec0-8ca965a4470d"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-29T22:00:00.000Z",
|
||||
"until": "2026-05-30T21:59:59.000Z",
|
||||
"locale": "cs",
|
||||
"emptyCalendarIds": false
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "afe20509-c476-48e9-83eb-fb02e161c6d8",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "aee6f9c4-1487-4934-a32a-8a7b1517271b",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "c646d60b-40ca-4f32-8a11-052ab90f5d2c",
|
||||
"start": "2026-05-30T07:00:00.000Z",
|
||||
"end": "2026-05-30T07:05:00.000Z",
|
||||
"note": "TEST poznamka z Claude Code",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "3ac6849a-12e2-4248-a99d-ec9a577ce820",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "Test 2 z Claude Code",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"b6555c7e-4e95-4657-b441-87c2c9a7b2ca"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-29T22:00:00.000Z",
|
||||
"until": "2026-05-30T21:59:59.000Z",
|
||||
"locale": "cs"
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "afe20509-c476-48e9-83eb-fb02e161c6d8",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "aee6f9c4-1487-4934-a32a-8a7b1517271b",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "c646d60b-40ca-4f32-8a11-052ab90f5d2c",
|
||||
"start": "2026-05-30T07:00:00.000Z",
|
||||
"end": "2026-05-30T07:05:00.000Z",
|
||||
"note": "TEST poznamka z Claude Code",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "3ac6849a-12e2-4248-a99d-ec9a577ce820",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "Test 2 z Claude Code",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
}
|
||||
],
|
||||
"recurringReservations": [
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "ccadcdbd-d5b3-47ec-9b18-414c6dd0d105",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "TEST denne",
|
||||
"rrule": {
|
||||
"frequency": "DAILY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T14:40:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T14:40:00.000Z",
|
||||
"end": "2026-05-30T14:45:00.000Z",
|
||||
"note": "TEST denne",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "280cc437-2ff0-4d74-b16a-a6175d2b1020",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T2",
|
||||
"rrule": {
|
||||
"frequency": "DAILY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"MO",
|
||||
"TU",
|
||||
"WE",
|
||||
"TH",
|
||||
"FR"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "89f850f5-19dc-48b8-a24d-9173b80aa095",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T3",
|
||||
"rrule": {
|
||||
"frequency": "WEEKLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:05:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:05:00.000Z",
|
||||
"end": "2026-05-30T15:10:00.000Z",
|
||||
"note": "T3",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "f38f7185-8050-46ee-a2c4-0ca590cc3ab9",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T4",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
11,
|
||||
13,
|
||||
15,
|
||||
17,
|
||||
19,
|
||||
21,
|
||||
23,
|
||||
25,
|
||||
27,
|
||||
29,
|
||||
31,
|
||||
33,
|
||||
35,
|
||||
37,
|
||||
39,
|
||||
41,
|
||||
43,
|
||||
45,
|
||||
47,
|
||||
49,
|
||||
51,
|
||||
53
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "357c63bc-6278-4867-acf6-e6d3124eec53",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T5",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
2,
|
||||
4,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
16,
|
||||
18,
|
||||
20,
|
||||
22,
|
||||
24,
|
||||
26,
|
||||
28,
|
||||
30,
|
||||
32,
|
||||
34,
|
||||
36,
|
||||
38,
|
||||
40,
|
||||
42,
|
||||
44,
|
||||
46,
|
||||
48,
|
||||
50,
|
||||
52
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:35:00.000Z",
|
||||
"end": "2026-05-30T15:40:00.000Z",
|
||||
"note": "T5",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "eee3904f-475d-4932-914a-fff9ada8fb6c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T6",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:45:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": [
|
||||
30
|
||||
],
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:45:00.000Z",
|
||||
"end": "2026-05-30T15:50:00.000Z",
|
||||
"note": "T6",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "95c5c675-68a2-4181-9d6d-1ebc6d2e6a4c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T7",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"-1SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:20:00.000Z",
|
||||
"end": "2026-05-30T15:25:00.000Z",
|
||||
"note": "T7",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"b6555c7e-4e95-4657-b441-87c2c9a7b2ca"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-29T22:00:00.000Z",
|
||||
"until": "2026-05-30T21:59:59.000Z",
|
||||
"locale": "cs"
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "afe20509-c476-48e9-83eb-fb02e161c6d8",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "aee6f9c4-1487-4934-a32a-8a7b1517271b",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "TEST",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
},
|
||||
{
|
||||
"id": "3ac6849a-12e2-4248-a99d-ec9a577ce820",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z",
|
||||
"note": "Test 2 z Claude Code",
|
||||
"done": null,
|
||||
"color": "CHARCOAL",
|
||||
"canceledAt": null,
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"request": null
|
||||
}
|
||||
],
|
||||
"recurringReservations": [
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "280cc437-2ff0-4d74-b16a-a6175d2b1020",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T2",
|
||||
"rrule": {
|
||||
"frequency": "DAILY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"MO",
|
||||
"TU",
|
||||
"WE",
|
||||
"TH",
|
||||
"FR"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "f38f7185-8050-46ee-a2c4-0ca590cc3ab9",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T4",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
11,
|
||||
13,
|
||||
15,
|
||||
17,
|
||||
19,
|
||||
21,
|
||||
23,
|
||||
25,
|
||||
27,
|
||||
29,
|
||||
31,
|
||||
33,
|
||||
35,
|
||||
37,
|
||||
39,
|
||||
41,
|
||||
43,
|
||||
45,
|
||||
47,
|
||||
49,
|
||||
51,
|
||||
53
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "357c63bc-6278-4867-acf6-e6d3124eec53",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T5",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
2,
|
||||
4,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
16,
|
||||
18,
|
||||
20,
|
||||
22,
|
||||
24,
|
||||
26,
|
||||
28,
|
||||
30,
|
||||
32,
|
||||
34,
|
||||
36,
|
||||
38,
|
||||
40,
|
||||
42,
|
||||
44,
|
||||
46,
|
||||
48,
|
||||
50,
|
||||
52
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:35:00.000Z",
|
||||
"end": "2026-05-30T15:40:00.000Z",
|
||||
"note": "T5",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "eee3904f-475d-4932-914a-fff9ada8fb6c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T6",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:45:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": [
|
||||
30
|
||||
],
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:45:00.000Z",
|
||||
"end": "2026-05-30T15:50:00.000Z",
|
||||
"note": "T6",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "95c5c675-68a2-4181-9d6d-1ebc6d2e6a4c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T7",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"-1SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-30T15:20:00.000Z",
|
||||
"end": "2026-05-30T15:25:00.000Z",
|
||||
"note": "T7",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"b6555c7e-4e95-4657-b441-87c2c9a7b2ca"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-30T22:00:00.000Z",
|
||||
"until": "2026-05-31T21:59:59.000Z",
|
||||
"locale": "cs",
|
||||
"emptyCalendarIds": false
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"b6555c7e-4e95-4657-b441-87c2c9a7b2ca"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-05-30T22:00:00.000Z",
|
||||
"until": "2026-05-31T21:59:59.000Z",
|
||||
"locale": "cs"
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [],
|
||||
"recurringReservations": [
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "ccadcdbd-d5b3-47ec-9b18-414c6dd0d105",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "TEST denne",
|
||||
"rrule": {
|
||||
"frequency": "DAILY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T14:40:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-31T14:40:00.000Z",
|
||||
"end": "2026-05-31T14:45:00.000Z",
|
||||
"note": "TEST denne",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "280cc437-2ff0-4d74-b16a-a6175d2b1020",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T2",
|
||||
"rrule": {
|
||||
"frequency": "DAILY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"MO",
|
||||
"TU",
|
||||
"WE",
|
||||
"TH",
|
||||
"FR"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "89f850f5-19dc-48b8-a24d-9173b80aa095",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T3",
|
||||
"rrule": {
|
||||
"frequency": "WEEKLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:05:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "f38f7185-8050-46ee-a2c4-0ca590cc3ab9",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T4",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
1,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
9,
|
||||
11,
|
||||
13,
|
||||
15,
|
||||
17,
|
||||
19,
|
||||
21,
|
||||
23,
|
||||
25,
|
||||
27,
|
||||
29,
|
||||
31,
|
||||
33,
|
||||
35,
|
||||
37,
|
||||
39,
|
||||
41,
|
||||
43,
|
||||
45,
|
||||
47,
|
||||
49,
|
||||
51,
|
||||
53
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "357c63bc-6278-4867-acf6-e6d3124eec53",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T5",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:35:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": [
|
||||
2,
|
||||
4,
|
||||
6,
|
||||
8,
|
||||
10,
|
||||
12,
|
||||
14,
|
||||
16,
|
||||
18,
|
||||
20,
|
||||
22,
|
||||
24,
|
||||
26,
|
||||
28,
|
||||
30,
|
||||
32,
|
||||
34,
|
||||
36,
|
||||
38,
|
||||
40,
|
||||
42,
|
||||
44,
|
||||
46,
|
||||
48,
|
||||
50,
|
||||
52
|
||||
]
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "eee3904f-475d-4932-914a-fff9ada8fb6c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T6",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:45:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": [
|
||||
30
|
||||
],
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "95c5c675-68a2-4181-9d6d-1ebc6d2e6a4c",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T7",
|
||||
"rrule": {
|
||||
"frequency": "MONTHLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-30T15:20:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": [
|
||||
"-1SA"
|
||||
],
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": []
|
||||
},
|
||||
{
|
||||
"recurringReservation": {
|
||||
"id": "f675ca4f-1169-4b3b-8266-b171d23849c8",
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"color": "CHARCOAL",
|
||||
"note": "T8",
|
||||
"rrule": {
|
||||
"frequency": "YEARLY",
|
||||
"interval": 1,
|
||||
"dtstart": "2026-05-31T15:05:00.000Z",
|
||||
"tzid": "Europe/Prague",
|
||||
"byweekday": null,
|
||||
"bymonthday": null,
|
||||
"byweekno": null
|
||||
}
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
"start": "2026-05-31T15:05:00.000Z",
|
||||
"end": "2026-05-31T15:10:00.000Z",
|
||||
"note": "T8",
|
||||
"color": "CHARCOAL"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"144c4e12-347c-49ca-9ec0-8ca965a4470d"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-06-02T22:00:00.000Z",
|
||||
"until": "2026-06-03T21:59:59.000Z",
|
||||
"locale": "cs",
|
||||
"emptyCalendarIds": false
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "bc275236-970f-4b88-887e-b4c5f286e3a9",
|
||||
"start": "2026-06-03T08:00:00.000Z",
|
||||
"end": "2026-06-03T08:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "bebb68b3-f9e1-48e0-9e14-b72e5781b4c4",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "86931ca3-cfd4-4aed-af66-244cecc691ee",
|
||||
"name": "Sylvie",
|
||||
"surname": "Rejfířová",
|
||||
"dob": "1980-06-01",
|
||||
"phone": "+420602266614",
|
||||
"identificationNumber": "8056010149",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "73844dfa-316f-47da-ac3d-2554ff5aec7f",
|
||||
"start": "2026-06-03T08:45:00.000Z",
|
||||
"end": "2026-06-03T09:00:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "97dd7ace-1668-479b-a09b-44d775e53227",
|
||||
"displayTitle": "Kontrola INR (Quick)",
|
||||
"extendedPatient": {
|
||||
"id": "d8c2f2b6-fdf7-462e-91de-fce908aaf3de",
|
||||
"name": "Jaroslav",
|
||||
"surname": "Kameník",
|
||||
"dob": "1940-05-10",
|
||||
"phone": "+420776702345",
|
||||
"identificationNumber": "400510088",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c2c96faa-4129-4815-a213-ffdd887d42f8",
|
||||
"start": "2026-06-03T07:00:00.000Z",
|
||||
"end": "2026-06-03T07:30:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "4ee1cee1-5ccd-425d-85b1-3896d850a784",
|
||||
"displayTitle": "Prohlídka při léčbě cukrovky",
|
||||
"extendedPatient": {
|
||||
"id": "0aeefc63-8599-4602-b731-b7c81e9106a2",
|
||||
"name": "Miloslav",
|
||||
"surname": "Hájek",
|
||||
"dob": "1974-10-24",
|
||||
"phone": "+420602262242",
|
||||
"identificationNumber": "7410241014",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "906ca466-eb83-4a65-bc2e-90020714d4e9",
|
||||
"start": "2026-06-03T09:00:00.000Z",
|
||||
"end": "2026-06-03T09:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "6790af69-4416-4ef8-9101-7e3f7d668320",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "7bcf8cea-efe7-4f90-8e91-c8f88ba72ee6",
|
||||
"name": "Denisa",
|
||||
"surname": "Ryšavá",
|
||||
"dob": "2007-10-24",
|
||||
"phone": "+420606815415",
|
||||
"identificationNumber": "0760245079",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a91481ba-cf7c-4968-bd54-8424565cae3d",
|
||||
"start": "2026-06-03T09:45:00.000Z",
|
||||
"end": "2026-06-03T09:55:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "c0ac9fdb-5a82-4306-9d1c-ed22110205fe",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "ec4db98b-cce8-473c-a47e-ef24bf61d3d8",
|
||||
"name": "Romana",
|
||||
"surname": "Ratkiewiczová",
|
||||
"dob": "1990-04-15",
|
||||
"phone": "+420737261867",
|
||||
"identificationNumber": "9054151128",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b5f01f0c-0c9f-42bb-a7bd-f0a725638d38",
|
||||
"start": "2026-06-03T10:00:00.000Z",
|
||||
"end": "2026-06-03T10:10:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "48d490fa-0fd1-4a16-aba8-79f275043345",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "d8d36c4d-19fc-4405-9bf9-f9a733fb2dad",
|
||||
"name": "Jana",
|
||||
"surname": "Ptáčková",
|
||||
"dob": "1947-09-17",
|
||||
"phone": "+420604363791",
|
||||
"identificationNumber": "475917011",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "44d6f66b-95b9-4bfb-b2c9-69338a7cae8f",
|
||||
"start": "2026-06-03T10:10:00.000Z",
|
||||
"end": "2026-06-03T10:20:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "30e1d256-eaaf-4a0b-aa13-cd511e4e309e",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "bb27b85a-8703-4768-86f4-2cbf4c196dd1",
|
||||
"name": "Karel",
|
||||
"surname": "Galus",
|
||||
"dob": "1946-06-14",
|
||||
"phone": "+420605230820",
|
||||
"identificationNumber": "460614110",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 211,
|
||||
"shortName": "ZPMV"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b128a573-849d-4bf2-9317-01142147e61e",
|
||||
"start": "2026-06-03T10:30:00.000Z",
|
||||
"end": "2026-06-03T10:50:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "bbd0e36a-5148-43d2-8095-fcf746586778",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "5a0a9ff0-bbe8-4fc7-a27d-b7b475ee2189",
|
||||
"name": "Lenka",
|
||||
"surname": "Balousova",
|
||||
"dob": "1972-03-28",
|
||||
"phone": "+420603560064",
|
||||
"identificationNumber": "7253282355",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c0bbc7bc-2491-4143-a6b9-59d4fab9df63",
|
||||
"start": "2026-06-03T10:50:00.000Z",
|
||||
"end": "2026-06-03T11:05:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "b0f01a56-6ae6-47fa-94bf-e693977e127b",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "3e1090b7-d0c2-4dd8-bbfe-dc464d2f1671",
|
||||
"name": "Lenka",
|
||||
"surname": "Vaněčková",
|
||||
"dob": "1943-03-17",
|
||||
"phone": "+420776599498",
|
||||
"identificationNumber": "435317067",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9d2f969b-da52-418c-8465-d29021beab49",
|
||||
"start": "2026-06-03T11:15:00.000Z",
|
||||
"end": "2026-06-03T11:25:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "019ec07d-b454-4231-9b49-9389fe675faa",
|
||||
"displayTitle": "Očkování - Klíšťová encefalitida",
|
||||
"extendedPatient": {
|
||||
"id": "865e0404-b2c8-4635-8d8d-df7a14275b14",
|
||||
"name": "Jiří",
|
||||
"surname": "Chomát",
|
||||
"dob": "1938-03-14",
|
||||
"phone": "+420737217617",
|
||||
"identificationNumber": "380314026",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
{
|
||||
"request": {
|
||||
"calendarIds": [
|
||||
"144c4e12-347c-49ca-9ec0-8ca965a4470d"
|
||||
],
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"since": "2026-06-02T22:00:00.000Z",
|
||||
"until": "2026-06-03T21:59:59.000Z",
|
||||
"locale": "cs"
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservations": [
|
||||
{
|
||||
"id": "bc275236-970f-4b88-887e-b4c5f286e3a9",
|
||||
"start": "2026-06-03T08:00:00.000Z",
|
||||
"end": "2026-06-03T08:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "bebb68b3-f9e1-48e0-9e14-b72e5781b4c4",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "86931ca3-cfd4-4aed-af66-244cecc691ee",
|
||||
"name": "Sylvie",
|
||||
"surname": "Rejfířová",
|
||||
"dob": "1980-06-01",
|
||||
"phone": "+420602266614",
|
||||
"identificationNumber": "8056010149",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "73844dfa-316f-47da-ac3d-2554ff5aec7f",
|
||||
"start": "2026-06-03T08:45:00.000Z",
|
||||
"end": "2026-06-03T09:00:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "97dd7ace-1668-479b-a09b-44d775e53227",
|
||||
"displayTitle": "Kontrola INR (Quick)",
|
||||
"extendedPatient": {
|
||||
"id": "d8c2f2b6-fdf7-462e-91de-fce908aaf3de",
|
||||
"name": "Jaroslav",
|
||||
"surname": "Kameník",
|
||||
"dob": "1940-05-10",
|
||||
"phone": "+420776702345",
|
||||
"identificationNumber": "400510088",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c2c96faa-4129-4815-a213-ffdd887d42f8",
|
||||
"start": "2026-06-03T07:00:00.000Z",
|
||||
"end": "2026-06-03T07:30:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "4ee1cee1-5ccd-425d-85b1-3896d850a784",
|
||||
"displayTitle": "Prohlídka při léčbě cukrovky",
|
||||
"extendedPatient": {
|
||||
"id": "0aeefc63-8599-4602-b731-b7c81e9106a2",
|
||||
"name": "Miloslav",
|
||||
"surname": "Hájek",
|
||||
"dob": "1974-10-24",
|
||||
"phone": "+420602262242",
|
||||
"identificationNumber": "7410241014",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "906ca466-eb83-4a65-bc2e-90020714d4e9",
|
||||
"start": "2026-06-03T09:00:00.000Z",
|
||||
"end": "2026-06-03T09:45:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "6790af69-4416-4ef8-9101-7e3f7d668320",
|
||||
"displayTitle": "Preventivní prohlídka nebo vstupní prohlídka",
|
||||
"extendedPatient": {
|
||||
"id": "7bcf8cea-efe7-4f90-8e91-c8f88ba72ee6",
|
||||
"name": "Denisa",
|
||||
"surname": "Ryšavá",
|
||||
"dob": "2007-10-24",
|
||||
"phone": "+420606815415",
|
||||
"identificationNumber": "0760245079",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "a91481ba-cf7c-4968-bd54-8424565cae3d",
|
||||
"start": "2026-06-03T09:45:00.000Z",
|
||||
"end": "2026-06-03T09:55:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "c0ac9fdb-5a82-4306-9d1c-ed22110205fe",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "ec4db98b-cce8-473c-a47e-ef24bf61d3d8",
|
||||
"name": "Romana",
|
||||
"surname": "Ratkiewiczová",
|
||||
"dob": "1990-04-15",
|
||||
"phone": "+420737261867",
|
||||
"identificationNumber": "9054151128",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 201,
|
||||
"shortName": "VoZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b5f01f0c-0c9f-42bb-a7bd-f0a725638d38",
|
||||
"start": "2026-06-03T10:00:00.000Z",
|
||||
"end": "2026-06-03T10:10:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "48d490fa-0fd1-4a16-aba8-79f275043345",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "d8d36c4d-19fc-4405-9bf9-f9a733fb2dad",
|
||||
"name": "Jana",
|
||||
"surname": "Ptáčková",
|
||||
"dob": "1947-09-17",
|
||||
"phone": "+420604363791",
|
||||
"identificationNumber": "475917011",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "44d6f66b-95b9-4bfb-b2c9-69338a7cae8f",
|
||||
"start": "2026-06-03T10:10:00.000Z",
|
||||
"end": "2026-06-03T10:20:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "30e1d256-eaaf-4a0b-aa13-cd511e4e309e",
|
||||
"displayTitle": "Očkování - Žloutenka A",
|
||||
"extendedPatient": {
|
||||
"id": "bb27b85a-8703-4768-86f4-2cbf4c196dd1",
|
||||
"name": "Karel",
|
||||
"surname": "Galus",
|
||||
"dob": "1946-06-14",
|
||||
"phone": "+420605230820",
|
||||
"identificationNumber": "460614110",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 211,
|
||||
"shortName": "ZPMV"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "b128a573-849d-4bf2-9317-01142147e61e",
|
||||
"start": "2026-06-03T10:30:00.000Z",
|
||||
"end": "2026-06-03T10:50:00.000Z",
|
||||
"note": null,
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "bbd0e36a-5148-43d2-8095-fcf746586778",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "5a0a9ff0-bbe8-4fc7-a27d-b7b475ee2189",
|
||||
"name": "Lenka",
|
||||
"surname": "Balousova",
|
||||
"dob": "1972-03-28",
|
||||
"phone": "+420603560064",
|
||||
"identificationNumber": "7253282355",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 207,
|
||||
"shortName": "OZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "c0bbc7bc-2491-4143-a6b9-59d4fab9df63",
|
||||
"start": "2026-06-03T10:50:00.000Z",
|
||||
"end": "2026-06-03T11:05:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "b0f01a56-6ae6-47fa-94bf-e693977e127b",
|
||||
"displayTitle": "Zdravotní obtíže",
|
||||
"extendedPatient": {
|
||||
"id": "3e1090b7-d0c2-4dd8-bbfe-dc464d2f1671",
|
||||
"name": "Lenka",
|
||||
"surname": "Vaněčková",
|
||||
"dob": "1943-03-17",
|
||||
"phone": "+420776599498",
|
||||
"identificationNumber": "435317067",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "9d2f969b-da52-418c-8465-d29021beab49",
|
||||
"start": "2026-06-03T11:15:00.000Z",
|
||||
"end": "2026-06-03T11:25:00.000Z",
|
||||
"note": "",
|
||||
"done": null,
|
||||
"color": null,
|
||||
"canceledAt": null,
|
||||
"calendarId": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
"request": {
|
||||
"id": "019ec07d-b454-4231-9b49-9389fe675faa",
|
||||
"displayTitle": "Očkování - Klíšťová encefalitida",
|
||||
"extendedPatient": {
|
||||
"id": "865e0404-b2c8-4635-8d8d-df7a14275b14",
|
||||
"name": "Jiří",
|
||||
"surname": "Chomát",
|
||||
"dob": "1938-03-14",
|
||||
"phone": "+420737217617",
|
||||
"identificationNumber": "380314026",
|
||||
"insuranceCompanyObject": {
|
||||
"code": 111,
|
||||
"shortName": "VZP"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"recurringReservations": []
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"request": {
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"color": "CHARCOAL",
|
||||
"note": "TEST poznamka z Claude Code",
|
||||
"timeSlotInput": {
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"start": "2026-05-30T07:00:00.000Z",
|
||||
"end": "2026-05-30T07:05:00.000Z"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservation": {
|
||||
"id": "c646d60b-40ca-4f32-8a11-052ab90f5d2c",
|
||||
"__typename": "Reservation"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"request": {
|
||||
"clinicSlug": "mudr-buzalkova",
|
||||
"color": "CHARCOAL",
|
||||
"note": "Test 2 z Claude Code",
|
||||
"timeSlotInput": {
|
||||
"calendarId": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"start": "2026-05-30T08:00:00.000Z",
|
||||
"end": "2026-05-30T08:05:00.000Z"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"reservation": {
|
||||
"id": "3ac6849a-12e2-4248-a99d-ec9a577ce820",
|
||||
"__typename": "Reservation"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Smazani rezervace / poznamky v Medevio kalendari.
|
||||
|
||||
Defaultni chovani:
|
||||
- jednorazova: smazat (cancel)
|
||||
- opakujici se: smazat tuto a nasledujici (ThisAndFuture)
|
||||
|
||||
Pouziti jako modul:
|
||||
from smaz_poznamku import smaz_jednorazovou, smaz_opakujici
|
||||
|
||||
smaz_jednorazovou("<reservation_uuid>")
|
||||
smaz_opakujici("<recurring_id>", date="2026-05-30T14:40:00.000Z") # default ThisAndFuture
|
||||
smaz_opakujici("<recurring_id>", date="...Z", update_type="All")
|
||||
smaz_opakujici("<recurring_id>", date="...Z", update_type="Single")
|
||||
|
||||
CLI:
|
||||
python smaz_poznamku.py --jednorazova <reservation_uuid>
|
||||
python smaz_poznamku.py --opakujici <recurring_id> --datum 2026-05-30T14:40:00.000Z
|
||||
python smaz_poznamku.py --opakujici <id> --datum ...Z --typ All
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
from dateutil import parser as dtparser, tz
|
||||
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
GRAPHQL_URL = "https://api.medevio.cz/graphql"
|
||||
CLINIC_SLUG = "mudr-buzalkova"
|
||||
PRAGUE_TZ = tz.gettz("Europe/Prague")
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
TOKEN_PATH = BASE_DIR / "token.txt"
|
||||
DEBUG_DIR = BASE_DIR / "debug"
|
||||
|
||||
VALID_UPDATE_TYPES = ("Single", "ThisAndFuture", "All")
|
||||
|
||||
MUTATION_SINGLE = """mutation UpdateReservation_CancelReservationByDoctor(
|
||||
$clinicSlug: String!, $reservationId: UUID!
|
||||
) {
|
||||
reservation: cancelReservationByDoctor(
|
||||
clinicSlug: $clinicSlug, reservationId: $reservationId
|
||||
) { id __typename }
|
||||
}"""
|
||||
|
||||
MUTATION_RECURRING = """mutation UpdateReservation_CancelRecurringReservationByDoctor(
|
||||
$input: RemoveRecurringReservationInput!
|
||||
) {
|
||||
success: removeDateFromRecurringReservation(input: $input)
|
||||
}"""
|
||||
|
||||
|
||||
def _load_token() -> str:
|
||||
token = TOKEN_PATH.read_text(encoding="utf-8").strip()
|
||||
if token.startswith("Bearer "):
|
||||
token = token.split(" ", 1)[1]
|
||||
return token
|
||||
|
||||
|
||||
def _headers() -> dict:
|
||||
return {
|
||||
"content-type": "application/json",
|
||||
"authorization": f"Bearer {_load_token()}",
|
||||
"origin": "https://my.medevio.cz",
|
||||
"referer": "https://my.medevio.cz/",
|
||||
}
|
||||
|
||||
|
||||
def _to_utc_iso(value) -> str:
|
||||
"""Prijme str/datetime/date a vrati '....000Z'."""
|
||||
if isinstance(value, str):
|
||||
if value.endswith("Z") and "T" in value:
|
||||
return value
|
||||
dt = dtparser.parse(value)
|
||||
elif isinstance(value, datetime):
|
||||
dt = value
|
||||
else:
|
||||
raise TypeError(f"Nelze prevest na datetime: {value!r}")
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=PRAGUE_TZ)
|
||||
return dt.astimezone(tz.UTC).strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
||||
|
||||
|
||||
def _post(payload: dict, label: str, save_debug: bool = True) -> dict:
|
||||
r = requests.post(GRAPHQL_URL, headers=_headers(), data=json.dumps(payload), timeout=30)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
|
||||
if save_debug:
|
||||
DEBUG_DIR.mkdir(exist_ok=True)
|
||||
p = DEBUG_DIR / f"smaz_{label}_{datetime.now():%Y%m%d_%H%M%S}.json"
|
||||
p.write_text(
|
||||
json.dumps({"request": payload["variables"], "response": data}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"[debug] {p}")
|
||||
|
||||
if "errors" in data:
|
||||
raise RuntimeError(f"GraphQL error: {data['errors']}")
|
||||
return data["data"]
|
||||
|
||||
|
||||
def smaz_jednorazovou(reservation_id: str, clinic_slug: str = CLINIC_SLUG) -> dict:
|
||||
"""Zrusi (cancel) jednorazovou rezervaci. Vraci {'id': ..., '__typename': ...}."""
|
||||
payload = {
|
||||
"operationName": "UpdateReservation_CancelReservationByDoctor",
|
||||
"variables": {"clinicSlug": clinic_slug, "reservationId": reservation_id},
|
||||
"query": MUTATION_SINGLE,
|
||||
}
|
||||
result = _post(payload, "single")["reservation"]
|
||||
print(f"OK zruseno: {result['id']}")
|
||||
return result
|
||||
|
||||
|
||||
def smaz_opakujici(
|
||||
recurring_id: str,
|
||||
date,
|
||||
update_type: str = "ThisAndFuture",
|
||||
clinic_slug: str = CLINIC_SLUG,
|
||||
) -> bool:
|
||||
"""Smaze opakujici se rezervaci.
|
||||
|
||||
Args:
|
||||
recurring_id: UUID `recurringReservation.id`
|
||||
date: datum konkretni instance (ISO str s Z, nebo datetime, nebo 'YYYY-MM-DD HH:MM' v lokal cas)
|
||||
update_type: 'Single' | 'ThisAndFuture' (default) | 'All'
|
||||
"""
|
||||
if update_type not in VALID_UPDATE_TYPES:
|
||||
raise ValueError(f"update_type musi byt {VALID_UPDATE_TYPES}, dostal '{update_type}'")
|
||||
payload = {
|
||||
"operationName": "UpdateReservation_CancelRecurringReservationByDoctor",
|
||||
"variables": {
|
||||
"input": {
|
||||
"clinicSlug": clinic_slug,
|
||||
"recurringReservationId": recurring_id,
|
||||
"date": _to_utc_iso(date),
|
||||
"updateType": update_type,
|
||||
}
|
||||
},
|
||||
"query": MUTATION_RECURRING,
|
||||
}
|
||||
success = _post(payload, f"recurring_{update_type}")["success"]
|
||||
print(f"OK smazano ({update_type}): {recurring_id} @ {payload['variables']['input']['date']} -> success={success}")
|
||||
return success
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Smazani rezervace v Medevio kalendari.")
|
||||
g = ap.add_mutually_exclusive_group(required=True)
|
||||
g.add_argument("--jednorazova", help="UUID jednorazove rezervace ke zruseni")
|
||||
g.add_argument("--opakujici", help="UUID opakujiciho se pravidla")
|
||||
ap.add_argument("--datum", help="Datum instance opakujici (ISO Z nebo 'YYYY-MM-DD HH:MM')")
|
||||
ap.add_argument("--typ", choices=VALID_UPDATE_TYPES, default="ThisAndFuture",
|
||||
help="Pro --opakujici. Default ThisAndFuture.")
|
||||
args = ap.parse_args()
|
||||
|
||||
if args.jednorazova:
|
||||
smaz_jednorazovou(args.jednorazova)
|
||||
else:
|
||||
if not args.datum:
|
||||
ap.error("--opakujici vyzaduje --datum")
|
||||
smaz_opakujici(args.opakujici, args.datum, update_type=args.typ)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,202 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Zapise poznamku lekare do Medevio kalendare (color=CHARCOAL).
|
||||
|
||||
Hlavni funkce: `zapis_poznamku()` - bere parametry:
|
||||
calendar_id UUID kalendare (Vlado / manzelka / ...)
|
||||
den date nebo str 'YYYY-MM-DD'
|
||||
cas str 'HH:MM' nebo time
|
||||
trvani_min int - delka v minutach
|
||||
poznamka str - text
|
||||
perioda None | str - "DAILY", "WEEKDAYS", atd. (zatim NotImplemented)
|
||||
color ECRFIconColor enum, default CHARCOAL
|
||||
clinic_slug default mudr-buzalkova
|
||||
|
||||
Vrati id vytvorene rezervace (str).
|
||||
|
||||
CLI:
|
||||
python zapis_poznamky.py --den 2026-06-03 --cas 09:00 --trvani 5 --poznamka "Text"
|
||||
python zapis_poznamky.py --den 2026-06-03 --cas 09:00 --trvani 5 --poznamka "Text" --kalendar manzelka
|
||||
"""
|
||||
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
from datetime import datetime, date, time as dtime, timedelta
|
||||
|
||||
import requests
|
||||
from dateutil import tz
|
||||
|
||||
try:
|
||||
sys.stdout.reconfigure(encoding="utf-8")
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
GRAPHQL_URL = "https://api.medevio.cz/graphql"
|
||||
CLINIC_SLUG = "mudr-buzalkova"
|
||||
PRAGUE_TZ = tz.gettz("Europe/Prague")
|
||||
|
||||
# Pojmenovane kalendare - viz pamet project-medevio-kalendar
|
||||
CALENDARS = {
|
||||
"vlado": "b6555c7e-4e95-4657-b441-87c2c9a7b2ca",
|
||||
"manzelka": "144c4e12-347c-49ca-9ec0-8ca965a4470d",
|
||||
}
|
||||
DEFAULT_CALENDAR = "vlado"
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent
|
||||
TOKEN_PATH = BASE_DIR / "token.txt"
|
||||
DEBUG_DIR = BASE_DIR / "debug"
|
||||
|
||||
MUTATION = """mutation CreateReservation_MakeReservationByDoctor(
|
||||
$clinicSlug: String!,
|
||||
$color: ECRFIconColor,
|
||||
$note: String!,
|
||||
$timeSlotInput: TimeSlotInput!
|
||||
) {
|
||||
reservation: makeReservationByDoctor(
|
||||
clinicSlug: $clinicSlug
|
||||
color: $color
|
||||
note: $note
|
||||
timeSlotInput: $timeSlotInput
|
||||
) {
|
||||
id
|
||||
__typename
|
||||
}
|
||||
}"""
|
||||
|
||||
|
||||
def _load_token() -> str:
|
||||
token = TOKEN_PATH.read_text(encoding="utf-8").strip()
|
||||
if token.startswith("Bearer "):
|
||||
token = token.split(" ", 1)[1]
|
||||
return token
|
||||
|
||||
|
||||
def _headers() -> dict:
|
||||
return {
|
||||
"content-type": "application/json",
|
||||
"authorization": f"Bearer {_load_token()}",
|
||||
"origin": "https://my.medevio.cz",
|
||||
"referer": "https://my.medevio.cz/",
|
||||
}
|
||||
|
||||
|
||||
def _to_utc_iso(dt: datetime) -> str:
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=PRAGUE_TZ)
|
||||
return dt.astimezone(tz.UTC).strftime("%Y-%m-%dT%H:%M:%S.000Z")
|
||||
|
||||
|
||||
def _resolve_calendar(calendar) -> str:
|
||||
"""Prijme UUID nebo nazev ('vlado', 'manzelka'). Vrati UUID."""
|
||||
if calendar in CALENDARS:
|
||||
return CALENDARS[calendar]
|
||||
if isinstance(calendar, str) and len(calendar) == 36 and calendar.count("-") == 4:
|
||||
return calendar
|
||||
raise ValueError(f"Neznamy kalendar: {calendar!r}. Pouzij UUID nebo jeden z {list(CALENDARS)}.")
|
||||
|
||||
|
||||
def _resolve_day(den) -> date:
|
||||
if isinstance(den, date) and not isinstance(den, datetime):
|
||||
return den
|
||||
if isinstance(den, datetime):
|
||||
return den.date()
|
||||
return datetime.strptime(str(den), "%Y-%m-%d").date()
|
||||
|
||||
|
||||
def _resolve_time(cas) -> dtime:
|
||||
if isinstance(cas, dtime):
|
||||
return cas
|
||||
return datetime.strptime(str(cas), "%H:%M").time()
|
||||
|
||||
|
||||
def zapis_poznamku(
|
||||
calendar: str = DEFAULT_CALENDAR,
|
||||
den=None,
|
||||
cas=None,
|
||||
trvani_min: int = 5,
|
||||
poznamka: str = "",
|
||||
perioda: str | None = None,
|
||||
color: str = "CHARCOAL",
|
||||
clinic_slug: str = CLINIC_SLUG,
|
||||
save_debug: bool = True,
|
||||
) -> str:
|
||||
"""Vytvori poznamku lekare v Medevio kalendari. Vraci id rezervace."""
|
||||
if perioda is not None:
|
||||
raise NotImplementedError(
|
||||
"Periodicita zatim neni implementovana - neznam format payloadu. "
|
||||
"Zachyt jednu opakujici se rezervaci pres Claude in Chrome a doplnime."
|
||||
)
|
||||
if den is None or cas is None:
|
||||
raise ValueError("Musis zadat 'den' a 'cas'.")
|
||||
|
||||
calendar_id = _resolve_calendar(calendar)
|
||||
d = _resolve_day(den)
|
||||
t = _resolve_time(cas)
|
||||
start_dt = datetime.combine(d, t).replace(tzinfo=PRAGUE_TZ)
|
||||
end_dt = start_dt + timedelta(minutes=int(trvani_min))
|
||||
|
||||
payload = {
|
||||
"operationName": "CreateReservation_MakeReservationByDoctor",
|
||||
"variables": {
|
||||
"clinicSlug": clinic_slug,
|
||||
"color": color,
|
||||
"note": poznamka,
|
||||
"timeSlotInput": {
|
||||
"calendarId": calendar_id,
|
||||
"start": _to_utc_iso(start_dt),
|
||||
"end": _to_utc_iso(end_dt),
|
||||
},
|
||||
},
|
||||
"query": MUTATION,
|
||||
}
|
||||
|
||||
r = requests.post(GRAPHQL_URL, headers=_headers(), data=json.dumps(payload), timeout=30)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
|
||||
if save_debug:
|
||||
DEBUG_DIR.mkdir(exist_ok=True)
|
||||
debug_path = DEBUG_DIR / f"poznamka_{datetime.now():%Y%m%d_%H%M%S}.json"
|
||||
debug_path.write_text(
|
||||
json.dumps({"request": payload["variables"], "response": data}, ensure_ascii=False, indent=2),
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(f"[debug] {debug_path}")
|
||||
|
||||
if "errors" in data:
|
||||
raise RuntimeError(f"GraphQL error: {data['errors']}")
|
||||
|
||||
res_id = data["data"]["reservation"]["id"]
|
||||
print(f"OK: {d} {t:%H:%M} +{trvani_min}min '{poznamka}' -> {res_id}")
|
||||
return res_id
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Zapis poznamku lekare do Medevio kalendare.")
|
||||
ap.add_argument("--kalendar", default=DEFAULT_CALENDAR,
|
||||
help=f"Jmeno ({'/'.join(CALENDARS)}) nebo UUID. Default '{DEFAULT_CALENDAR}'.")
|
||||
ap.add_argument("--den", required=True, help="YYYY-MM-DD")
|
||||
ap.add_argument("--cas", required=True, help="HH:MM (lokalni cas Europe/Prague)")
|
||||
ap.add_argument("--trvani", type=int, default=5, help="delka v minutach (default 5)")
|
||||
ap.add_argument("--poznamka", required=True, help="text poznamky")
|
||||
ap.add_argument("--perioda", default=None,
|
||||
help="opakovani (zatim NotImplemented)")
|
||||
ap.add_argument("--color", default="CHARCOAL")
|
||||
args = ap.parse_args()
|
||||
|
||||
zapis_poznamku(
|
||||
calendar=args.kalendar,
|
||||
den=args.den,
|
||||
cas=args.cas,
|
||||
trvani_min=args.trvani,
|
||||
poznamka=args.poznamka,
|
||||
perioda=args.perioda,
|
||||
color=args.color,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user