changes to he pdf sending
This commit is contained in:
+47
-40
@@ -2206,7 +2206,19 @@ def build_module_config_string(package_list: list) -> str:
|
||||
]
|
||||
return " ".join(config_parts)
|
||||
|
||||
def background_booking_provisioning(app_instance, prov_id, subdomain, package_list, user_id, school_name, user_email, username, address, price, software_name):
|
||||
def background_booking_provisioning(
|
||||
app_instance,
|
||||
prov_id,
|
||||
subdomain,
|
||||
package_list,
|
||||
user_id,
|
||||
school_name,
|
||||
user_email,
|
||||
username,
|
||||
address,
|
||||
price,
|
||||
software_name="Invario Inventarsystem"
|
||||
):
|
||||
"""Hintergrund-Worker, der die Tenant-Bereitstellung über das Host-Watcher-Triggersystem auslöst."""
|
||||
with app_instance.app_context():
|
||||
req_client, req_col = _get_collection("instance_requests")
|
||||
@@ -2214,7 +2226,7 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
# 1. Status auf "in_progress" setzen
|
||||
req_col.update_one({"_id": ObjectId(prov_id)}, {"$set": {"provision_status": "in_progress"}})
|
||||
|
||||
# 2. Naechsten Port und Admin-Passwort ermitteln
|
||||
# 2. Nächsten Port und Admin-Passwort ermitteln
|
||||
inst_client_check, inst_col_check = _get_collection("instances")
|
||||
try:
|
||||
existing_instances = list(inst_col_check.find({}, {"https_port": 1, "port": 1}))
|
||||
@@ -2232,7 +2244,7 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
# Generiere den korrekten Modul-String
|
||||
module_config_str = build_module_config_string(package_list)
|
||||
|
||||
# 3. Trigger-Datei fuer den Host-Watcher schreiben
|
||||
# 3. Trigger-Datei für den Host-Watcher schreiben
|
||||
os.makedirs(TRIGGER_DIR, exist_ok=True)
|
||||
trigger_file = os.path.join(TRIGGER_DIR, f"{subdomain}.json")
|
||||
|
||||
@@ -2248,13 +2260,13 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
with open(trigger_file, "w") as f:
|
||||
json.dump(trigger_payload, f)
|
||||
|
||||
print(f"[INFO] Trigger-Datei fuer Host-Watcher erstellt: {trigger_file} mit Payload: {trigger_payload}")
|
||||
print(f"[INFO] Trigger-Datei für Host-Watcher erstellt: {trigger_file} mit Payload: {trigger_payload}")
|
||||
|
||||
# 4. Instanz-Eintrag in der Datenbank registrieren
|
||||
domain = f"{subdomain}.invario-software.de"
|
||||
instance_doc = {
|
||||
"owner_id": user_id,
|
||||
"owner_username": username, # <--- HIER HINZUGEFÜGT
|
||||
"owner_username": username,
|
||||
"school_name": school_name,
|
||||
"subdomain": subdomain,
|
||||
"domain": domain,
|
||||
@@ -2272,9 +2284,11 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
finally:
|
||||
inst_client.close()
|
||||
|
||||
# 5. Bestaetigungs-E-Mail versenden
|
||||
# 5. Bestätigungs-E-Mail inkl. Vertrag & Anhängen versenden
|
||||
try:
|
||||
if user_email:
|
||||
formatted_date = datetime.today().strftime('%d.%m.%Y')
|
||||
|
||||
send_accreditation_email(
|
||||
recipient=user_email,
|
||||
domain=domain,
|
||||
@@ -2283,9 +2297,10 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
school_name=school_name,
|
||||
address=address,
|
||||
price=price,
|
||||
date=_utc_now_iso(),
|
||||
software_name=software_name,
|
||||
date=formatted_date,
|
||||
software_name=software_name
|
||||
)
|
||||
|
||||
except Exception as mail_err:
|
||||
print(f"[WARNING] E-Mail-Versand fehlgeschlagen: {mail_err}")
|
||||
|
||||
@@ -2302,10 +2317,10 @@ def background_booking_provisioning(app_instance, prov_id, subdomain, package_li
|
||||
"updated_at": _utc_now_iso()
|
||||
}}
|
||||
)
|
||||
print(f"[SUCCESS] Provisioning-Trigger erfolgreich gesendet fuer {subdomain}")
|
||||
print(f"[SUCCESS] Provisioning-Trigger erfolgreich gesendet für {subdomain}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[ERROR] Async Provisioning fehlgeschlagen fuer {subdomain}:")
|
||||
print(f"[ERROR] Async Provisioning fehlgeschlagen für {subdomain}:")
|
||||
traceback.print_exc()
|
||||
req_col.update_one({"_id": ObjectId(prov_id)}, {"$set": {"provision_status": "failed", "last_error": str(e)}})
|
||||
finally:
|
||||
@@ -2350,7 +2365,6 @@ def booking_payment():
|
||||
|
||||
flow_config = BOOKING_FLOW_MAP[booking_flow]
|
||||
|
||||
# Auslesen aller Formularfelder (inkl. tenant_slug und Rechnungsdaten)
|
||||
form_data = {
|
||||
"contact_person": _sanitize_text(request.values.get("contact_person") or "", 120),
|
||||
"school_name": _sanitize_text(request.values.get("school_name") or "", 160),
|
||||
@@ -2426,21 +2440,8 @@ def booking_payment():
|
||||
assigned_admin_display_name = assigned_admin.get("display_name") if assigned_admin else ""
|
||||
assigned_admin_email = (assigned_admin.get("email") if assigned_admin else "") or BOOKING_ADMIN_EMAIL_FALLBACK
|
||||
|
||||
message = (
|
||||
f"{flow_config['message_prefix']} {selected_package} {flow_config['message_suffix']}\n"
|
||||
f"Ansprechpartner: {form_data['contact_person']}\n"
|
||||
f"Schule: {form_data['school_name']} (Dienstst.-Nr: {form_data['school_number']})\n"
|
||||
f"E-Mail: {form_data['contact_email']}\n"
|
||||
f"Telefon: {form_data['contact_phone'] or '-'}\n"
|
||||
f"Schulträger/Amt: {form_data['billing_organization']}\n"
|
||||
f"Rechnungsadresse: {form_data['billing_street']}, {form_data['billing_zip']} {form_data['billing_city']}\n"
|
||||
f"Kassenzeichen: {form_data['billing_reference'] or '-'}\n"
|
||||
f"Gewünschte Subdomain: {form_data['tenant_slug']}\n"
|
||||
f"Notizen: {form_data['notes'] or '-'}"
|
||||
)
|
||||
|
||||
try:
|
||||
# FLOW 1: Beratung / Gesprächs-Buchung
|
||||
# FLOW 1: Consultation / Chat
|
||||
if booking_flow == "consultation":
|
||||
client, col = _get_collection("chat_messages")
|
||||
try:
|
||||
@@ -2449,7 +2450,7 @@ def booking_payment():
|
||||
"username": session.get("username"),
|
||||
"sender": session.get("display_name") or session.get("username"),
|
||||
"sender_role": "user",
|
||||
"message": message,
|
||||
"message": f"Gesprächswunsch bezüglich: {selected_package}",
|
||||
"created_at": _utc_now_iso(),
|
||||
"booking_flow": booking_flow,
|
||||
"booking_package": package_raw,
|
||||
@@ -2465,18 +2466,16 @@ def booking_payment():
|
||||
flash(f"Gesprächstermin für {selected_package} wurde an das Team gesendet.", "success")
|
||||
return redirect(url_for("user_chat"))
|
||||
|
||||
# FLOW 2: Kostenpflichtige Direkt-Buchung mit Provisioning via Watcher
|
||||
# FLOW 2: Direktbuchung mit Provisioning via Host-Watcher
|
||||
if booking_flow == "payment":
|
||||
booking_number = f"BOOK-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
|
||||
|
||||
# Schul-URL aus dem Formular bevorzugen
|
||||
raw_base = form_data.get("tenant_slug") or form_data.get("school_name") or session.get("username") or booking_number
|
||||
base = _slugify_subdomain(raw_base).lower()[:51]
|
||||
|
||||
# Prüfung auf doppelte Subdomains via MongoDB 'instances' Collection
|
||||
inst_check_client, inst_check_col = _get_collection("instances")
|
||||
inst_check_client, inst_col_check = _get_collection("instances")
|
||||
try:
|
||||
existing_docs = list(inst_check_col.find({}, {"subdomain": 1}))
|
||||
existing_docs = list(inst_col_check.find({}, {"subdomain": 1}))
|
||||
existing_subdomains = [d.get("subdomain") for d in existing_docs if d.get("subdomain")]
|
||||
except Exception as e:
|
||||
print(f"[WARNING] Konnte bestehende Subdomains nicht prüfen: {e}")
|
||||
@@ -2523,29 +2522,37 @@ def booking_payment():
|
||||
username = session.get("username")
|
||||
user_email = session.get("email") or form_data.get("contact_email")
|
||||
address_process = f"{form_data['billing_street']}, {form_data['billing_zip']} {form_data['billing_city']}"
|
||||
price_str = f"{total_price:.2f}".replace('.', ',')
|
||||
|
||||
# Startet den asynchronen Provisioning-Thread
|
||||
# Startet den asynchronen Provisioning-Thread mit exakten Parametern
|
||||
thread = threading.Thread(
|
||||
target=background_booking_provisioning,
|
||||
args=(app_obj, prov_id, subdomain, package_list, user_id, form_data["school_name"], user_email, username, address_process, total_price, selected_package)
|
||||
args=(
|
||||
app_obj,
|
||||
prov_id,
|
||||
subdomain,
|
||||
package_list,
|
||||
user_id,
|
||||
form_data["school_name"],
|
||||
user_email,
|
||||
username,
|
||||
address_process,
|
||||
price_str,
|
||||
selected_package
|
||||
)
|
||||
)
|
||||
thread.start()
|
||||
print(f"[INFO] Background Provisioning Trigger gestartet für Subdomain: {subdomain}")
|
||||
|
||||
# ANPASSUNG FÜR BESSERE WARTEZEIT:
|
||||
# Wir geben Metadaten mit, wie lange das Setup ca. dauern wird.
|
||||
if is_json_request:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"slug": subdomain,
|
||||
"message": "Instanz wird eingerichtet...",
|
||||
"estimated_seconds": 45, # Erwartete Dauer in Sekunden (anpassbar)
|
||||
"status_poll_interval_ms": 3000 # Wie oft soll das Frontend fragen? (3 Sek)
|
||||
"estimated_seconds": 45,
|
||||
"status_poll_interval_ms": 3000
|
||||
}), 200
|
||||
|
||||
# Falls es KEIN AJAX-Request war:
|
||||
# Wir hängen den Parameter "wait_for_slug" an, damit die "my_instance_management"-Seite weiß,
|
||||
# dass sie sofort ein Lade-Overlay für diesen spezifischen Tenant öffnen muss.
|
||||
flash(f"Buchung für {selected_package} wurde erfasst. Deine Instanz wird jetzt automatisch eingerichtet.", "success")
|
||||
return redirect(url_for("my_instance_management", wait_for_slug=subdomain))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user