# -*- coding: utf-8 -*- """Hilfsfunktionen für Praxis-Beitritt / Empfang-Provisioning (testbar, ohne Tk).""" from __future__ import annotations from typing import Any, Dict, Optional def normalize_invite_code(raw: str) -> str: s = (raw or "").strip().upper().replace(" ", "") for ch in ("\u2011", "\u2013", "\u2014", "\u2212"): s = s.replace(ch, "-") return s def should_show_connect_practice_dialog(user_profile: dict | None) -> bool: """Erststart-Dialog nur wenn noch keine practice_id gesetzt ist.""" if not isinstance(user_profile, dict): return True return not (str(user_profile.get("practice_id") or "").strip()) def build_empfang_provision_payload( user_profile: dict, *, forced_practice_id: Optional[str] = None, ) -> Optional[Dict[str, Any]]: """Baut POST /empfang/auth/provision Body aus lokalem Profil.""" if not isinstance(user_profile, dict): return None name = str(user_profile.get("name") or "").strip() email = str(user_profile.get("email") or "").strip() clinic = str(user_profile.get("clinic") or "").strip() lic_k = str(user_profile.get("license_key") or "").strip() edn = str(user_profile.get("empfang_display_name") or "").strip() if (not name or name == "Benutzer") and edn: name = edn if (not name or name == "Benutzer") and email and lic_k: part = email.split("@", 1)[0].strip() if part and len(part) >= 2: name = part if not name or name == "Benutzer": return None pw = email.split("@")[0] if email else name.lower() if len(pw) < 4: pw = pw + "1234" payload: Dict[str, Any] = {"name": name, "email": email, "password": pw} if clinic: payload["practice_name"] = clinic if lic_k: payload["license_key"] = lic_k dsp = str(user_profile.get("specialty") or "").strip() dti = str(user_profile.get("title") or "").strip() if dsp: payload["desktop_specialty"] = dsp if dti: payload["desktop_title"] = dti pending_inv = normalize_invite_code(str(user_profile.get("pending_chat_invite_code") or "")) if pending_inv: payload["invite_code"] = pending_inv prior_pid = str(user_profile.get("practice_id") or "").strip() existing_pid = (forced_practice_id or prior_pid or "").strip() if existing_pid: payload["practice_id"] = existing_pid return payload def apply_join_existing_practice_response( user_profile: dict, response: dict, ) -> tuple[dict, bool]: """Wendet erfolgreiche /license/join_existing_practice Antwort auf Profil an.""" if not isinstance(user_profile, dict): user_profile = {} if not isinstance(response, dict): return user_profile, False changed = False npid = str(response.get("practice_id") or "").strip() if npid and npid != str(user_profile.get("practice_id") or "").strip(): user_profile["practice_id"] = npid changed = True uid = str(response.get("user_id") or "").strip() if uid and uid != str(user_profile.get("empfang_user_id") or "").strip(): user_profile["empfang_user_id"] = uid changed = True dn = str(response.get("display_name") or "").strip() if dn and dn != str(user_profile.get("empfang_display_name") or "").strip(): user_profile["empfang_display_name"] = dn changed = True if user_profile.pop("pending_chat_invite_code", None): changed = True return user_profile, changed def merge_resolve_invite_into_profile( user_profile: dict, invite_code: str, *, practice_id: str = "", practice_name: str = "", ) -> dict: """Speichert validierten Einladungscode bis Provision/Join.""" prof = dict(user_profile or {}) code = normalize_invite_code(invite_code) if code: prof["pending_chat_invite_code"] = code if practice_id: prof["_pending_join_practice_id"] = practice_id.strip() if practice_name: prof["_pending_join_practice_name"] = practice_name.strip() return prof