update
This commit is contained in:
@@ -21,6 +21,7 @@ import smtplib
|
||||
import sqlite3
|
||||
import string
|
||||
import time
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
from decimal import Decimal
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
@@ -115,6 +116,8 @@ def _ensure_storage() -> None:
|
||||
con.execute("ALTER TABLE licenses ADD COLUMN current_period_end INTEGER")
|
||||
if "license_key" not in cols:
|
||||
con.execute("ALTER TABLE licenses ADD COLUMN license_key TEXT")
|
||||
if "practice_id" not in cols:
|
||||
con.execute("ALTER TABLE licenses ADD COLUMN practice_id TEXT")
|
||||
con.commit()
|
||||
|
||||
|
||||
@@ -409,6 +412,59 @@ def _log_event(kind: str, payload: Dict[str, Any]) -> None:
|
||||
f.write(json.dumps(rec, ensure_ascii=False, default=_decimal_default) + "\n")
|
||||
|
||||
|
||||
def _new_practice_id() -> str:
|
||||
"""Gleiches Format wie empfang_routes._generate_practice_id (Mandanten-ID)."""
|
||||
return f"prac_{uuid.uuid4().hex[:12]}"
|
||||
|
||||
|
||||
def _sync_empfang_practice_from_license(
|
||||
practice_id: str,
|
||||
customer_email: Optional[str],
|
||||
display_name: str,
|
||||
) -> None:
|
||||
"""Empfang-Praxisdatei mit SQLite-Lizenz synchronisieren (eine Wahrheit)."""
|
||||
pid = (practice_id or "").strip()
|
||||
if not pid:
|
||||
return
|
||||
try:
|
||||
from empfang_routes import _ensure_practice
|
||||
except Exception as exc:
|
||||
print(f"[STRIPE] empfang_routes Import: {exc}")
|
||||
return
|
||||
try:
|
||||
em = (customer_email or "").strip()
|
||||
name = (display_name or "").strip() or (em.split("@")[0] if "@" in em else "Meine Praxis")
|
||||
_ensure_practice(pid, name=name, admin_email=em)
|
||||
except Exception as exc:
|
||||
print(f"[STRIPE] _ensure_practice: {exc}")
|
||||
|
||||
|
||||
def lookup_practice_id_for_license_email(email: str) -> Optional[str]:
|
||||
"""Liefert die serverseitig gespeicherte practice_id zur Kunden-E-Mail (Lizenz ↔ Praxis)."""
|
||||
_ensure_storage()
|
||||
e = (email or "").strip().lower()
|
||||
if not e:
|
||||
return None
|
||||
try:
|
||||
with sqlite3.connect(DB_PATH) as con:
|
||||
row = con.execute(
|
||||
"""
|
||||
SELECT practice_id FROM licenses
|
||||
WHERE lower(customer_email) = ?
|
||||
AND practice_id IS NOT NULL
|
||||
AND trim(practice_id) != ''
|
||||
ORDER BY updated_at DESC
|
||||
LIMIT 1
|
||||
""",
|
||||
(e,),
|
||||
).fetchone()
|
||||
if not row or not row[0]:
|
||||
return None
|
||||
return str(row[0]).strip()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _upsert_license(
|
||||
*,
|
||||
subscription_id: str,
|
||||
@@ -422,27 +478,36 @@ def _upsert_license(
|
||||
current_period_end: Optional[int],
|
||||
license_key: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Upsert license row. Returns the license_key (generated if not yet set)."""
|
||||
"""Upsert license row. Returns the license_key (generated if not yet set).
|
||||
|
||||
Jede Lizenzzeile erhält spätestens hier eine stabile practice_id (Mandant),
|
||||
damit Stripe-Webhook und Desktop/Empfang dieselbe ID nutzen.
|
||||
"""
|
||||
now = int(time.time())
|
||||
with sqlite3.connect(DB_PATH) as con:
|
||||
existing_key = None
|
||||
existing_pid = ""
|
||||
row = con.execute(
|
||||
"SELECT license_key FROM licenses WHERE subscription_id = ?",
|
||||
"SELECT license_key, practice_id FROM licenses WHERE subscription_id = ?",
|
||||
(subscription_id,),
|
||||
).fetchone()
|
||||
if row and row[0]:
|
||||
existing_key = row[0]
|
||||
if row:
|
||||
if row[0]:
|
||||
existing_key = row[0]
|
||||
if row[1]:
|
||||
existing_pid = str(row[1]).strip()
|
||||
|
||||
final_key = existing_key or license_key or _generate_license_key()
|
||||
final_pid = existing_pid or _new_practice_id()
|
||||
|
||||
con.execute(
|
||||
"""
|
||||
INSERT INTO licenses(
|
||||
subscription_id, customer_id, status, lookup_key,
|
||||
allowed_users, devices_per_user, customer_email, client_reference_id,
|
||||
current_period_end, updated_at, license_key
|
||||
current_period_end, updated_at, license_key, practice_id
|
||||
)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
ON CONFLICT(subscription_id) DO UPDATE SET
|
||||
customer_id=excluded.customer_id,
|
||||
status=excluded.status,
|
||||
@@ -453,7 +518,12 @@ def _upsert_license(
|
||||
client_reference_id=COALESCE(excluded.client_reference_id, client_reference_id),
|
||||
current_period_end=COALESCE(excluded.current_period_end, current_period_end),
|
||||
updated_at=excluded.updated_at,
|
||||
license_key=COALESCE(license_key, excluded.license_key)
|
||||
license_key=COALESCE(license_key, excluded.license_key),
|
||||
practice_id=CASE
|
||||
WHEN licenses.practice_id IS NOT NULL AND trim(licenses.practice_id) != ''
|
||||
THEN licenses.practice_id
|
||||
ELSE excluded.practice_id
|
||||
END
|
||||
""",
|
||||
(
|
||||
subscription_id,
|
||||
@@ -467,9 +537,21 @@ def _upsert_license(
|
||||
current_period_end,
|
||||
now,
|
||||
final_key,
|
||||
final_pid,
|
||||
),
|
||||
)
|
||||
con.commit()
|
||||
|
||||
row2 = con.execute(
|
||||
"SELECT practice_id, customer_email FROM licenses WHERE subscription_id = ?",
|
||||
(subscription_id,),
|
||||
).fetchone()
|
||||
if row2:
|
||||
pid_s = str(row2[0]).strip() if row2[0] else ""
|
||||
em = (str(row2[1]).strip() if row2[1] else "") or (customer_email or "").strip()
|
||||
if pid_s:
|
||||
disp = em.split("@")[0] if "@" in em else "Meine Praxis"
|
||||
_sync_empfang_practice_from_license(pid_s, em or None, disp)
|
||||
return final_key
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user