implementation for the warenkorb system
This commit is contained in:
+58
-34
@@ -1972,34 +1972,54 @@ def preise():
|
||||
@app.route('/preise/book-option', methods=['POST'])
|
||||
@login_required
|
||||
def book_option_package():
|
||||
package_raw = _sanitize_text(request.form.get("package") or "", 40).lower()
|
||||
# Unterstützt "packages" (Warenkorb) und Fallback auf "package" (altes Formular)
|
||||
packages_raw = _sanitize_text(request.form.get("packages") or request.form.get("package") or "", 200).lower()
|
||||
booking_flow = _sanitize_text(request.form.get("flow") or "payment", 24).lower()
|
||||
|
||||
if booking_flow not in BOOKING_FLOW_MAP:
|
||||
booking_flow = "payment"
|
||||
|
||||
selected_package = BOOKING_PACKAGE_MAP.get(package_raw)
|
||||
if not selected_package:
|
||||
flash("Ungültige Buchungsoption ausgewählt.", "error")
|
||||
if not packages_raw:
|
||||
flash("Keine Buchungsoption ausgewählt.", "error")
|
||||
return redirect(url_for("preise"))
|
||||
|
||||
return redirect(url_for("booking_payment", package=package_raw, flow=booking_flow))
|
||||
return redirect(url_for("booking_payment", packages=packages_raw, flow=booking_flow))
|
||||
|
||||
|
||||
@app.route('/booking/payment', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def booking_payment():
|
||||
package_raw = _sanitize_text((request.values.get("package") or ""), 40).lower()
|
||||
booking_flow = _sanitize_text((request.values.get("flow") or "payment"), 24).lower()
|
||||
# Hole kommagetrennte Liste (z. B. "inventarsystem,terminverwaltung")
|
||||
packages_str = _sanitize_text(request.values.get("packages") or request.values.get("package") or "", 200).lower()
|
||||
booking_flow = _sanitize_text(request.values.get("flow") or "payment", 24).lower()
|
||||
|
||||
if booking_flow not in BOOKING_FLOW_MAP:
|
||||
booking_flow = "payment"
|
||||
|
||||
selected_package = BOOKING_PACKAGE_MAP.get(package_raw)
|
||||
package_price = BOOKING_PRICE_MAP.get(package_raw)
|
||||
if not selected_package:
|
||||
flash("Ungültige Buchungsoption ausgewählt.", "error")
|
||||
if not packages_str:
|
||||
flash("Keine Buchungsoption ausgewählt.", "error")
|
||||
return redirect(url_for("preise"))
|
||||
|
||||
package_list = [p.strip() for p in packages_str.split(',') if p.strip()]
|
||||
|
||||
# Validiere Pakete, sammle Namen und berechne Gesamtpreis
|
||||
selected_package_names = []
|
||||
total_price = 0.0
|
||||
for pkg in package_list:
|
||||
name = BOOKING_PACKAGE_MAP.get(pkg)
|
||||
if name:
|
||||
selected_package_names.append(name)
|
||||
total_price += BOOKING_PRICE_MAP.get(pkg, 0.0)
|
||||
else:
|
||||
flash(f"Ungültige Buchungsoption: {pkg}", "error")
|
||||
return redirect(url_for("preise"))
|
||||
|
||||
# Zusammengefasster String für Frontend und Datenbank (z.B. "Inventarsystem, Terminplaner")
|
||||
selected_package = ", ".join(selected_package_names)
|
||||
package_raw = packages_str # Speichert alle raw-keys für DB
|
||||
|
||||
flow_config = BOOKING_FLOW_MAP[booking_flow]
|
||||
|
||||
form_data = {
|
||||
"contact_person": _sanitize_text(request.values.get("contact_person") or "", 120),
|
||||
"school_name": _sanitize_text(request.values.get("school_name") or "", 160),
|
||||
@@ -2018,7 +2038,7 @@ def booking_payment():
|
||||
review_data = {
|
||||
"package": selected_package,
|
||||
"package_key": package_raw,
|
||||
"package_price": package_price,
|
||||
"package_price": total_price,
|
||||
"flow": booking_flow,
|
||||
"title": flow_config["title"],
|
||||
"intro": flow_config["intro"],
|
||||
@@ -2031,6 +2051,7 @@ def booking_payment():
|
||||
if request.method == "GET":
|
||||
return render_template("schnell_buchung.html", **review_data)
|
||||
|
||||
# --- POST Logik & Validierung ---
|
||||
required_fields = {
|
||||
"contact_person": "Ansprechpartner",
|
||||
"school_name": "Schule/Einrichtung",
|
||||
@@ -2039,6 +2060,7 @@ def booking_payment():
|
||||
"billing_zip": "PLZ",
|
||||
"billing_city": "Ort",
|
||||
}
|
||||
|
||||
missing_labels = [label for key, label in required_fields.items() if not form_data.get(key)]
|
||||
if missing_labels:
|
||||
flash(f"Bitte folgende Pflichtfelder ausfüllen: {', '.join(missing_labels)}.", "error")
|
||||
@@ -2079,20 +2101,17 @@ def booking_payment():
|
||||
"message": message,
|
||||
"created_at": _utc_now_iso(),
|
||||
"booking_flow": booking_flow,
|
||||
"booking_package": package_raw,
|
||||
"booking_package": package_raw, # Hier steht nun z.B. "inventarsystem,terminverwaltung"
|
||||
"booking_data": form_data,
|
||||
}
|
||||
)
|
||||
|
||||
if booking_flow == "payment":
|
||||
# Do NOT create an invoice directly. Instead request provisioning via server_steering
|
||||
booking_number = f"BOOK-{datetime.utcnow().strftime('%Y%m%d%H%M%S')}"
|
||||
|
||||
# Build a subdomain from the school name (fallback to username)
|
||||
# Use lowercase, sanitized school name and check for existing instances.
|
||||
raw_base = form_data.get("school_name") or session.get("username") or booking_number
|
||||
base = _slugify_subdomain(raw_base).lower()[:51]
|
||||
|
||||
# Check existing instances and require the user to choose a different name on conflict
|
||||
try:
|
||||
existing = steering.instace.list() or []
|
||||
except Exception:
|
||||
@@ -2103,11 +2122,10 @@ def booking_payment():
|
||||
return render_template("schnell_buchung.html", **review_data)
|
||||
|
||||
subdomain = base[:63]
|
||||
|
||||
provision_status = "not_started"
|
||||
provision_port = None
|
||||
provision_error = ""
|
||||
provision_config_ok = False
|
||||
provision_config_ok = True # Startet mit True, wird False wenn ein Modul fehlschlägt
|
||||
|
||||
try:
|
||||
try:
|
||||
@@ -2115,6 +2133,7 @@ def booking_payment():
|
||||
except Exception as e:
|
||||
port = False
|
||||
provision_error = str(e)
|
||||
provision_config_ok = False
|
||||
|
||||
if port and port is not False:
|
||||
provision_status = "started"
|
||||
@@ -2123,19 +2142,24 @@ def booking_payment():
|
||||
except Exception:
|
||||
provision_port = port
|
||||
|
||||
# Configure module if applicable
|
||||
module = None
|
||||
if package_raw in {"inventarsystem", "buecherei", "terminverwaltung", "emailversand", "starter", "advanced"}:
|
||||
module = package_raw
|
||||
if module:
|
||||
# Multi-Modul-Konfiguration: Startpaket wird in Inventar + Bücherei aufgeschlüsselt
|
||||
modules_to_provision = set()
|
||||
for pkg in package_list:
|
||||
if pkg == "startpaket":
|
||||
modules_to_provision.update(["inventarsystem", "buecherei"])
|
||||
elif pkg in {"inventarsystem", "buecherei", "terminverwaltung", "emailversand", "starter", "advanced"}:
|
||||
modules_to_provision.add(pkg)
|
||||
|
||||
# Einzelne Module in der erstellten Instanz editieren/aktivieren
|
||||
for mod in modules_to_provision:
|
||||
try:
|
||||
edit_ok = steering.instace.edit(subdomain, module)
|
||||
provision_config_ok = bool(edit_ok)
|
||||
if not provision_config_ok and not provision_error:
|
||||
provision_error = f"Module configuration failed for {module}"
|
||||
edit_ok = steering.instace.edit(subdomain, mod)
|
||||
if not edit_ok:
|
||||
provision_config_ok = False
|
||||
provision_error += f" | Edit failed for {mod}"
|
||||
except Exception as e:
|
||||
provision_config_ok = False
|
||||
provision_error = str(e)
|
||||
provision_error += f" | {mod}: {str(e)}"
|
||||
else:
|
||||
provision_status = "failed"
|
||||
if not provision_error:
|
||||
@@ -2149,7 +2173,7 @@ def booking_payment():
|
||||
"booking_number": booking_number,
|
||||
"package": package_raw,
|
||||
"package_label": selected_package,
|
||||
"amount_eur": BOOKING_PRICE_MAP.get(package_raw, 0.0),
|
||||
"amount_eur": total_price,
|
||||
"booking_flow": booking_flow,
|
||||
"booking_data": form_data,
|
||||
"assigned_admin_username": assigned_admin_username,
|
||||
@@ -2159,7 +2183,7 @@ def booking_payment():
|
||||
"provision_status": provision_status,
|
||||
"provision_port": provision_port or "",
|
||||
"provision_config_ok": provision_config_ok,
|
||||
"provision_error": provision_error,
|
||||
"provision_error": provision_error.strip(" | "),
|
||||
"created_at": _utc_now_iso(),
|
||||
"source": "booking_payment",
|
||||
}
|
||||
@@ -2173,8 +2197,8 @@ def booking_payment():
|
||||
req_client.close()
|
||||
|
||||
except PyMongoError:
|
||||
flash("Buchungsanfrage konnte nicht gesendet werden.", "error")
|
||||
return redirect(url_for("booking_payment", package=package_raw, flow=booking_flow))
|
||||
flash("Buchungsanfrage konnte nicht gesendet werden. Bitte versuchen Sie es erneut.", "error")
|
||||
return redirect(url_for("booking_payment", packages=package_raw, flow=booking_flow))
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
@@ -2185,13 +2209,13 @@ def booking_payment():
|
||||
else f"Buchung für {selected_package} wurde erfolgreich erfasst. Die Rechnung wird per E-Mail versendet."
|
||||
)
|
||||
flash(success_text, "success")
|
||||
|
||||
if booking_flow == "payment":
|
||||
return redirect(url_for("my_invoices"))
|
||||
else:
|
||||
return redirect(url_for("user_chat"))
|
||||
|
||||
|
||||
|
||||
@app.route('/instance_request/delete', methods=['POST'])
|
||||
@login_required
|
||||
def instance_request_delete():
|
||||
|
||||
Reference in New Issue
Block a user