implementation of the verification email for the admin
This commit is contained in:
+63
-1
@@ -27,7 +27,12 @@ from bson.binary import Binary
|
||||
import user as user_store
|
||||
import buchungen
|
||||
import server_steering as steering
|
||||
from modules.emailservice.email import send_register_token, send_accreditation_email, send_trial_notification
|
||||
from modules.emailservice.email import (
|
||||
send_register_token,
|
||||
send_accreditation_email,
|
||||
send_trial_notification,
|
||||
send_booking_admin_notification,
|
||||
)
|
||||
import secrets
|
||||
import requests
|
||||
from server_steering import Instance
|
||||
@@ -2411,6 +2416,37 @@ def background_booking_provisioning(
|
||||
)
|
||||
print(f"[WARNING] E-Mail-Versand fehlgeschlagen: {mail_err}")
|
||||
|
||||
booking_request = req_col.find_one({"_id": ObjectId(prov_id)}) or {}
|
||||
booking_data = booking_request.get("booking_data") or {}
|
||||
admin_email_sent = send_booking_admin_notification({
|
||||
"booking_number": booking_request.get("booking_number"),
|
||||
"username": username,
|
||||
"school_name": school_name,
|
||||
"contact_person": booking_data.get("contact_person"),
|
||||
"contact_email": booking_data.get("contact_email") or user_email,
|
||||
"contact_phone": booking_data.get("contact_phone"),
|
||||
"school_number": booking_data.get("school_number"),
|
||||
"billing_organization": booking_data.get("billing_organization"),
|
||||
"billing_street": booking_data.get("billing_street"),
|
||||
"billing_zip": booking_data.get("billing_zip"),
|
||||
"billing_city": booking_data.get("billing_city"),
|
||||
"billing_reference": booking_data.get("billing_reference"),
|
||||
"package": booking_request.get("package_label") or booking_request.get("package"),
|
||||
"amount_eur": booking_request.get("amount_eur"),
|
||||
"booking_flow": booking_request.get("booking_flow"),
|
||||
"invoice_id": booking_request.get("invoice_id"),
|
||||
"subdomain": effective_subdomain,
|
||||
"domain": domain,
|
||||
"payment_due_at": booking_request.get("due_date") or expires_at,
|
||||
"avv_version": booking_data.get("avv_version"),
|
||||
"legal_consents_accepted_at": booking_data.get("legal_consents_accepted_at"),
|
||||
"notes": booking_data.get("notes"),
|
||||
})
|
||||
req_col.update_one(
|
||||
{"_id": ObjectId(prov_id)},
|
||||
{"$set": {"admin_email_status": "sent" if admin_email_sent else "failed", "admin_email_updated_at": _utc_now_iso()}},
|
||||
)
|
||||
|
||||
# 8. Status in instance_requests auf "ready" setzen
|
||||
update_fields = {
|
||||
"provision_status": "ready",
|
||||
@@ -3153,6 +3189,31 @@ def booking_payment():
|
||||
finally:
|
||||
req_client.close()
|
||||
|
||||
admin_email_sent = send_booking_admin_notification({
|
||||
"booking_number": booking_number,
|
||||
"username": session.get("username"),
|
||||
"school_name": form_data.get("school_name"),
|
||||
"contact_person": form_data.get("contact_person"),
|
||||
"contact_email": form_data.get("contact_email") or user_email,
|
||||
"contact_phone": form_data.get("contact_phone"),
|
||||
"school_number": form_data.get("school_number"),
|
||||
"billing_organization": form_data.get("billing_organization"),
|
||||
"billing_street": form_data.get("billing_street"),
|
||||
"billing_zip": form_data.get("billing_zip"),
|
||||
"billing_city": form_data.get("billing_city"),
|
||||
"billing_reference": form_data.get("billing_reference"),
|
||||
"package": selected_package,
|
||||
"amount_eur": total_price,
|
||||
"booking_flow": booking_flow,
|
||||
"invoice_id": invoice_id,
|
||||
"subdomain": subdomain,
|
||||
"domain": reuse_instance.get("domain") or f"{subdomain}.invario-software.de",
|
||||
"payment_due_at": (date.today() + timedelta(days=PAYMENT_GRACE_DAYS)).isoformat(),
|
||||
"avv_version": form_data.get("avv_version"),
|
||||
"legal_consents_accepted_at": form_data.get("legal_consents_accepted_at"),
|
||||
"notes": form_data.get("notes"),
|
||||
})
|
||||
|
||||
email_status = "not_sent"
|
||||
if user_email:
|
||||
try:
|
||||
@@ -3181,6 +3242,7 @@ def booking_payment():
|
||||
{"$set": {
|
||||
"email_status": email_status,
|
||||
"email_recipient": user_email or "",
|
||||
"admin_email_status": "sent" if admin_email_sent else "failed",
|
||||
"email_updated_at": _utc_now_iso(),
|
||||
}},
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.application import MIMEApplication
|
||||
from html import escape
|
||||
import smtplib
|
||||
import time
|
||||
import os
|
||||
@@ -237,6 +238,50 @@ def send_trial_notification(
|
||||
"""
|
||||
return send(recipient, subject, text_body=text_body, html_body=html_body)
|
||||
|
||||
|
||||
def send_booking_admin_notification(booking: dict, recipient: str = "info@invario-software.de") -> bool:
|
||||
"""Notify the internal address about every completed product booking."""
|
||||
labels = {
|
||||
"booking_number": "Buchungsnummer",
|
||||
"username": "Benutzername",
|
||||
"school_name": "Schule",
|
||||
"contact_person": "Ansprechpartner",
|
||||
"contact_email": "Dienstliche E-Mail",
|
||||
"contact_phone": "Telefon",
|
||||
"school_number": "Dienststellennummer",
|
||||
"billing_organization": "Rechnungsempfänger",
|
||||
"billing_street": "Rechnungsstraße",
|
||||
"billing_zip": "Rechnungs-PLZ",
|
||||
"billing_city": "Rechnungsort",
|
||||
"billing_reference": "Kassenzeichen / Aktenzeichen",
|
||||
"package": "Gebuchte Produkte",
|
||||
"amount_eur": "Betrag netto",
|
||||
"booking_flow": "Buchungsfluss",
|
||||
"invoice_id": "Rechnungs-ID",
|
||||
"subdomain": "Subdomain",
|
||||
"domain": "Domain",
|
||||
"payment_due_at": "Zahlungsziel",
|
||||
"avv_version": "AVV-Fassung",
|
||||
"legal_consents_accepted_at": "Rechtsannahmen bestätigt am",
|
||||
"notes": "Notizen",
|
||||
}
|
||||
rows = [(label, str(booking.get(key) or "-")) for key, label in labels.items()]
|
||||
text_body = "Neue Produktbuchung\n\n" + "\n".join(f"{label}: {value}" for label, value in rows)
|
||||
html_rows = "".join(
|
||||
f"<tr><td><strong>{escape(label)}</strong></td><td>{escape(value)}</td></tr>"
|
||||
for label, value in rows
|
||||
)
|
||||
html_body = f"""
|
||||
<div style="font-family: Arial, sans-serif; color: #333333;">
|
||||
<h2>Neue Produktbuchung</h2>
|
||||
<table cellpadding="6" cellspacing="0" border="1" style="border-collapse: collapse; border-color: #d9e2e8;">
|
||||
{html_rows}
|
||||
</table>
|
||||
<p style="color:#64748b;">Das Initialpasswort wird aus Sicherheitsgründen nicht per Admin-Benachrichtigung versendet.</p>
|
||||
</div>
|
||||
"""
|
||||
return send(recipient, "Neue Produktbuchung bei Invario", text_body=text_body, html_body=html_body)
|
||||
|
||||
def send_password_reset_token(email: str, token: str) -> bool:
|
||||
"""Sends a professionally styled password reset token to the user."""
|
||||
subject = "Aktion erforderlich: Ihr Passwort-Zurücksetzungs-Code für Invario"
|
||||
|
||||
Reference in New Issue
Block a user