diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dbf6918 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# Python +__pycache__/ +*.py[cod] +*.pyo +*.pyd + +# Virtual environment +.venv/ +venv/ + +# PyCharm / IDE +.idea/ +*.iml + +# OS +.DS_Store +Thumbs.db + +# Logs & temp +*.log +*.tmp + +# Generated / data (adjust if needed) +data/ +output/ +exports/ diff --git a/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py b/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py index 2492756..f4225cb 100644 --- a/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py +++ b/10ReadPozadavky/PRAVIDELNE_5_SaveToFileSystem incremental.py @@ -49,7 +49,7 @@ DB_CONFIG = { "charset": "utf8mb4", } -BASE_DIR = Path(r"z:\Dropbox\Ordinace\Dokumentace_ke_zpracování\MP") +BASE_DIR = Path(r"u:\Dropbox\Ordinace\Dokumentace_ke_zpracování\MP") BASE_DIR.mkdir(parents=True, exist_ok=True) diff --git a/30 ManipulacePoznámek/102 Zapiš ID request do nejnovějšího otevřeného požadavku.py b/30 ManipulacePoznámek/102 Zapiš ID request do nejnovějšího otevřeného požadavku.py index ec3254e..66db1fb 100644 --- a/30 ManipulacePoznámek/102 Zapiš ID request do nejnovějšího otevřeného požadavku.py +++ b/30 ManipulacePoznámek/102 Zapiš ID request do nejnovějšího otevřeného požadavku.py @@ -5,6 +5,7 @@ import requests import mysql.connector from pathlib import Path import sys +from datetime import datetime # UTF-8 handling try: @@ -18,6 +19,11 @@ except: TOKEN_PATH = Path("token.txt") GRAPHQL_URL = "https://api.medevio.cz/graphql" +# --- ZPRACOVÁNÍ --- +# Zadejte počet požadavků ke zpracování. +# 0 znamená zpracovat VŠECHNY nesynchronizované požadavky. +PROCESS_LIMIT = 10 # <-- Používáme PROCESS_LIMIT + # --- MySQL DB --- DB_CONFIG = { "host": "192.168.1.76", @@ -40,51 +46,86 @@ def read_token(p: Path) -> str: # === DB Funkce === -def get_latest_open_request_id_from_db(): +def get_requests_to_process_from_db(limit): """ - Získá ID, Titul, Jméno a Příjmení nejnovějšího otevřeného požadavku z MySQL. + Získá seznam požadavků (ID, Titul, Jméno, Příjmení) k synchronizaci z MySQL. + Použije LIMIT, pokud limit > 0. """ - print("🔍 Připojuji se k MySQL a hledám ID nejnovějšího otevřeného požadavku...") + if limit == 0: + print("🔍 Připojuji se k MySQL a hledám **VŠECHNY** nesynchronizované požadavky...") + else: + print(f"🔍 Připojuji se k MySQL a hledám **{limit}** nesynchronizovaných požadavků...") + + requests_list = [] + conn = None try: conn = mysql.connector.connect(**DB_CONFIG) cursor = conn.cursor() - # SQL dotaz: Nyní vybíráme navíc jméno a příjmení pacienta + # Základní SQL dotaz query = """ SELECT id, displayTitle, pacient_jmeno, pacient_prijmeni FROM pozadavky WHERE doneAt IS NULL + AND noteSyncedAt IS NULL ORDER BY updatedAt DESC - LIMIT 1; """ + # Podmíněné přidání LIMIT klauzule + if limit > 0: + query += f"LIMIT {limit};" + else: + query += ";" + cursor.execute(query) - result = cursor.fetchone() + results = cursor.fetchall() - cursor.close() - conn.close() - - if result: + for result in results: request_id, display_title, jmeno, prijmeni = result - print(f"✅ Nalezen požadavek ID: {request_id} (Titul: {display_title})") - print(f" Pacient: **{prijmeni} {jmeno}**") # Vypíšeme pro snadnou kontrolu - return { + requests_list.append({ "id": request_id, "displayTitle": display_title, "jmeno": jmeno, "prijmeni": prijmeni - } + }) - print("❌ Nebyl nalezen žádný otevřený požadavek v DB.") - return None + cursor.close() + + if requests_list: + print(f"✅ Nalezeno {len(requests_list)} požadavků ke zpracování.") + else: + print("❌ Nebyl nalezen žádný nesynchronizovaný otevřený požadavek v DB.") + + return requests_list except mysql.connector.Error as err: print(f"❌ Chyba při připojení/dotazu MySQL: {err}") - return None + return [] + finally: + if conn and conn.is_connected(): + conn.close() -# === GraphQL Operace === -# Tyto GraphQL dotazy jsou beze změny +def update_db_sync_time(request_id, conn): + """Aktualizuje sloupec noteSyncedAt v tabulce pozadavky. Používá existující připojení.""" + cursor = conn.cursor() + + current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + + update_query = """ + UPDATE pozadavky + SET noteSyncedAt = %s + WHERE id = %s; + """ + + cursor.execute(update_query, (current_time, request_id)) + conn.commit() + + cursor.close() + print(f" (DB: Čas synchronizace pro {request_id} uložen)") + + +# === GraphQL Operace (Beze Změny) === QUERY_GET_NOTE = r""" query ClinicRequestNotes_Get($patientRequestId: String!) { @@ -103,6 +144,14 @@ mutation ClinicRequestNotes_Update($noteInput: UpdateClinicPatientRequestNoteInp } """ +MUTATION_CREATE_NOTE = r""" +mutation ClinicRequestNotes_Create($noteInput: CreateClinicPatientRequestNoteInput!) { + createClinicPatientRequestNote(noteInput: $noteInput) { + id + } +} +""" + def gql(query, variables, token): """Obecná funkce pro volání GraphQL endpointu.""" @@ -120,63 +169,92 @@ def gql(query, variables, token): def get_internal_note(request_id, token): """Získá jedinou interní poznámku (obsah a ID) pro daný požadavek.""" - print(f"🔍 Načítám poznámku z Medevia k požadavku {request_id}...") data = gql(QUERY_GET_NOTE, {"patientRequestId": request_id}, token) notes = data.get("data", {}).get("notes", []) - - if notes: - print("✅ Interní poznámka nalezena.") - return notes[0] - - print(f"⚠️ Interní poznámka pro požadavek {request_id} neexistuje.") - return None + return notes[0] if notes else None def update_internal_note(note_id, new_content, token): """Aktualizuje obsah poznámky v Medeviu.""" variables = {"noteInput": {"id": note_id, "content": new_content}} - print(f"📝 Odesílám aktualizaci poznámky {note_id}...") return gql(MUTATION_UPDATE_NOTE, variables, token) +def create_internal_note(request_id, content, token): + """Vytvoří novou interní poznámku k požadavku v Medeviu.""" + variables = {"noteInput": {"requestId": request_id, "content": content}} + return gql(MUTATION_CREATE_NOTE, variables, token) + + # === MAIN === def main(): token = read_token(TOKEN_PATH) - # 1. Zjistit ID a jméno pacienta z TVÉ DB - latest_request = get_latest_open_request_id_from_db() - if not latest_request: + # 1. Získat seznam ID požadavků ke zpracování (používáme PROCESS_LIMIT) + requests_to_process = get_requests_to_process_from_db(PROCESS_LIMIT) + + if not requests_to_process: return - request_id = latest_request["id"] + # Pro update DB time otevřeme připojení jednou a použijeme ho v cyklu + conn = mysql.connector.connect(**DB_CONFIG) - # 2. Získat existující interní poznámku z Medevia - note = get_internal_note(request_id, token) - if not note: - return + print("\n=============================================") + print(f"START ZPRACOVÁNÍ {len(requests_to_process)} POŽADAVKŮ") + print("=============================================\n") - note_id = note["id"] - old_content = note["content"] or "" + for idx, request in enumerate(requests_to_process, 1): + request_id = request["id"] - # 3. Vytvořit nový obsah (ID požadavku jako první řádek) - # Text, který vložíme na začátek - prepend_text = f"ID DB Synchronizace: {request_id}\n" - new_content = prepend_text + old_content + print( + f"[{idx}/{len(requests_to_process)}] Zpracovávám požadavek: {request['prijmeni']} {request['jmeno']} (ID: {request_id})") - print("--- Nový obsah který odešlu (začátek) ---") - print(f"-> {prepend_text.strip()}") - print("------------------------------------------") + # 2. Vytvořit text, který chceme přidat/vytvořit + prepend_text = f"ID: {request_id}\n" - # 4. Aktualizovat poznámku v Medeviu - try: - update_internal_note(note_id, new_content, token) - print(f"\n✅ Úspěch! Poznámka {note_id} k požadavku {request_id} byla aktualizována v Medeviu.") - print(f" **Zkontroluj požadavek pacienta: {latest_request['prijmeni']} {latest_request['jmeno']}**") - except requests.exceptions.HTTPError as e: - print(f"\n❌ Chyba při aktualizaci Medevio API: {e}") - except Exception as e: - print(f"\n❌ Neočekávaná chyba: {e}") + # 3. Pokusit se získat existující interní poznámku z Medevia + note = get_internal_note(request_id, token) + + medevio_update_success = False + + if note: + # A) POZNÁMKA EXISTUJE -> AKTUALIZOVAT + note_id = note["id"] + old_content = note["content"] or "" + new_content = prepend_text + old_content + + try: + # Odeslání aktualizace + update_internal_note(note_id, new_content, token) + print(f" (Medevio: Poznámka {note_id} **aktualizována**.)") + medevio_update_success = True + except requests.exceptions.HTTPError as e: + print(f" ❌ Chyba při aktualizaci Medevio API: {e}") + + else: + # B) POZNÁMKA NEEXISTUJE -> VYTVOŘIT + new_content = prepend_text.strip() + + try: + # Odeslání vytvoření + result = create_internal_note(request_id, new_content, token) + new_note_id = result.get("data", {}).get("createClinicPatientRequestNote", {}).get("id", "N/A") + print(f" (Medevio: Nová poznámka {new_note_id} **vytvořena**.)") + medevio_update_success = True + except requests.exceptions.HTTPError as e: + print(f" ❌ Chyba při vytváření Medevio API: {e}") + + # 4. AKTUALIZACE ČASOVÉHO RAZÍTKA V DB + if medevio_update_success: + update_db_sync_time(request_id, conn) + + print("---------------------------------------------") + + # Uzavřeme připojení k DB po dokončení cyklu + if conn and conn.is_connected(): + conn.close() + print("\n✅ Všechny požadavky zpracovány. Připojení k DB uzavřeno.") if __name__ == "__main__":