Compare commits

...

2 Commits

Author SHA1 Message Date
9726738a8a Fehler bei Anlage korrigiert 2026-04-03 18:31:33 +02:00
123ba4ca41 Anlage Mandant incl Admin und Groups und Folder 2026-04-03 18:28:24 +02:00
3 changed files with 148 additions and 7 deletions

View File

@ -1,6 +1,7 @@
import logging import logging
import os import os
import re import re
import shutil
from datetime import datetime from datetime import datetime
from logging.handlers import RotatingFileHandler from logging.handlers import RotatingFileHandler
@ -494,6 +495,11 @@ def admin_mandanten():
kontakt_email = request.form.get("kontakt_email", "").strip() kontakt_email = request.form.get("kontakt_email", "").strip()
level = request.form.get("level", "0").strip() level = request.form.get("level", "0").strip()
admin_name = request.form.get("admin_name", "").strip()
admin_email = request.form.get("admin_email", "").strip().lower()
admin_password = request.form.get("admin_password", "")
admin_password2 = request.form.get("admin_password2", "")
email_pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$" email_pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$"
error_message = None error_message = None
@ -507,6 +513,21 @@ def admin_mandanten():
elif not re.match(email_pattern, kontakt_email): elif not re.match(email_pattern, kontakt_email):
error_message = "Bitte eine gültige Kontakt-E-Mail eingeben." error_message = "Bitte eine gültige Kontakt-E-Mail eingeben."
elif not admin_name:
error_message = "Admin User Name ist ein Pflichtfeld."
elif not admin_email:
error_message = "Admin User E-Mail ist ein Pflichtfeld."
elif not re.match(email_pattern, admin_email):
error_message = "Bitte eine gültige Admin E-Mail-Adresse eingeben."
elif not admin_password:
error_message = "Admin Passwort ist ein Pflichtfeld."
elif not admin_password2:
error_message = "Bitte Admin Passwort bestätigen."
elif admin_password != admin_password2:
error_message = "Die beiden Admin-Passwörter stimmen nicht überein."
elif len(admin_password) < 8:
error_message = "Das Admin Passwort muss mindestens 8 Zeichen lang sein."
if error_message: if error_message:
cur.execute(""" cur.execute("""
SELECT id, kuerzel, name, kontakt_email, level SELECT id, kuerzel, name, kontakt_email, level
@ -534,16 +555,72 @@ def admin_mandanten():
"name": name, "name": name,
"kontakt_email": kontakt_email, "kontakt_email": kontakt_email,
"level": level, "level": level,
}, "admin_name": admin_name,
"admin_email": admin_email,
}
**get_current_user() **get_current_user()
) )
cur.execute("""
SELECT id
FROM app_user
WHERE lower(email) = %s
""", (admin_email,))
existing_admin_user = cur.fetchone()
if existing_admin_user:
error_message = "Ein Benutzer mit der Admin E-Mail existiert bereits."
cur.execute(""" cur.execute("""
INSERT INTO mandant (kuerzel, name, kontakt_email, level) INSERT INTO mandant (kuerzel, name, kontakt_email, level)
VALUES (%s, %s, %s, %s) VALUES (%s, %s, %s, %s)
RETURNING id
""", (kuerzel, name, kontakt_email, int(level or 0))) """, (kuerzel, name, kontakt_email, int(level or 0)))
new_mandant_id = cur.fetchone()[0]
# Standardgruppen für den neuen Mandanten
cur.execute("""
INSERT INTO app_group (mandant_id, group_name)
VALUES (%s, %s)
RETURNING id
""", (new_mandant_id, "Useradministration"))
useradmin_group_id = cur.fetchone()[0]
cur.execute("""
INSERT INTO app_group (mandant_id, group_name)
VALUES (%s, %s)
RETURNING id
""", (new_mandant_id, "Contentmanager"))
contentmanager_group_id = cur.fetchone()[0]
# erster Admin-User
admin_password_hash = generate_password_hash(admin_password)
cur.execute("""
INSERT INTO app_user (email, name, mandant_id, password_hash, status)
VALUES (%s, %s, %s, %s, %s)
RETURNING id
""", (admin_email, admin_name, new_mandant_id, admin_password_hash, 1))
new_admin_user_id = cur.fetchone()[0]
# User beiden Gruppen zuordnen
cur.execute("""
INSERT INTO user_group (user_id, group_id, mandant_id)
VALUES (%s, %s, %s)
""", (new_admin_user_id, useradmin_group_id, new_mandant_id))
cur.execute("""
INSERT INTO user_group (user_id, group_id, mandant_id)
VALUES (%s, %s, %s)
""", (new_admin_user_id, contentmanager_group_id, new_mandant_id))
conn.commit() conn.commit()
# Verzeichnis anlegen
mandant_dir = os.path.join(Config.FILES_DIR, str(new_mandant_id))
os.makedirs(mandant_dir, exist_ok=True)
elif action == "update": elif action == "update":
mandant_id = request.form.get("id") mandant_id = request.form.get("id")
kuerzel = request.form.get("kuerzel", "").strip() kuerzel = request.form.get("kuerzel", "").strip()
@ -563,9 +640,17 @@ def admin_mandanten():
elif action == "delete": elif action == "delete":
mandant_id = request.form.get("id") mandant_id = request.form.get("id")
cur.execute("DELETE FROM mandant WHERE id = %s", (int(mandant_id),)) mandant_id_int = int(mandant_id)
# Verzeichnis vor/nach dem Delete entfernen
mandant_dir = os.path.join(Config.FILES_DIR, str(mandant_id_int))
cur.execute("DELETE FROM mandant WHERE id = %s", (mandant_id_int,))
conn.commit() conn.commit()
if os.path.isdir(mandant_dir):
shutil.rmtree(mandant_dir, ignore_errors=True)
cur.close() cur.close()
conn.close() conn.close()
return redirect(url_for("admin_mandanten")) return redirect(url_for("admin_mandanten"))
@ -1150,7 +1235,7 @@ def dokument_upload(item_id):
final_name_part = item["default_filename"] or original_filename final_name_part = item["default_filename"] or original_filename
stored_filename = f"{item_id}-{secure_filename(final_name_part)}" stored_filename = f"{item_id}-{secure_filename(final_name_part)}"
mandant_dir = os.path.join("/files", str(mandant_id)) mandant_dir = os.path.join("/app/files", str(mandant_id))
os.makedirs(mandant_dir, exist_ok=True) os.makedirs(mandant_dir, exist_ok=True)
full_path = os.path.join(mandant_dir, stored_filename) full_path = os.path.join(mandant_dir, stored_filename)
@ -1205,7 +1290,7 @@ def dokument_upload(item_id):
@contentmanager_required @contentmanager_required
def dokument_delete(item_id): def dokument_delete(item_id):
mandant_id = session.get("mandant_id") mandant_id = session.get("mandant_id")
mandant_dir = os.path.join("/files", str(mandant_id)) mandant_dir = os.path.join("/app/files", str(mandant_id))
conn = get_connection() conn = get_connection()
cur = conn.cursor() cur = conn.cursor()
@ -1260,7 +1345,7 @@ def dokument_file(item_id):
abort(404) abort(404)
stored_filename = row[0] stored_filename = row[0]
mandant_dir = os.path.join("/files", str(mandant_id)) mandant_dir = os.path.join("/app/files", str(mandant_id))
return send_from_directory(mandant_dir, stored_filename) return send_from_directory(mandant_dir, stored_filename)
@app.template_filter("datetime") @app.template_filter("datetime")

View File

@ -11,9 +11,11 @@ class Config:
DB_PORT = os.getenv("DB_PORT", "5432") DB_PORT = os.getenv("DB_PORT", "5432")
LOG_DIR = os.getenv("LOG_DIR", "./logs") LOG_DIR = os.getenv("LOG_DIR", "./logs")
FILES_DIR = os.getenv("FILES_DIR", "/app/files")
COUNTRY_VAT_LABELS = { COUNTRY_VAT_LABELS = {
"DE": "inkl. 19% USt", "DE": "inkl. 19% USt",
"AT": "inkl. 20% USt", "AT": "inkl. 20% USt",
"CH": "exkl. MwSt", "CH": "exkl. MwSt",
} }

View File

@ -59,6 +59,29 @@
min="0"> min="0">
</div> </div>
<div class="form-row">
<label for="admin_name">Admin User Name</label>
<input type="text" id="admin_name" name="admin_name"
value="{{ form_values.admin_name if form_values else '' }}" required>
</div>
<div class="form-row">
<label for="admin_email">Admin User E-Mail</label>
<input type="email" id="admin_email" name="admin_email"
value="{{ form_values.admin_email if form_values else '' }}" required>
</div>
<div class="form-row">
<label for="admin_password">Admin Passwort</label>
<input type="password" id="admin_password" name="admin_password" required>
</div>
<div class="form-row">
<label for="admin_password2">Admin Passwort bestätigen</label>
<input type="password" id="admin_password2" name="admin_password2" required>
</div>
<div class="form-row form-row-full"> <div class="form-row form-row-full">
<div id="mandant-create-error" class="error-box" style="display: none;"></div> <div id="mandant-create-error" class="error-box" style="display: none;"></div>
<button type="submit" class="btn-primary">Mandant anlegen</button> <button type="submit" class="btn-primary">Mandant anlegen</button>
@ -173,6 +196,37 @@
errorBox.innerHTML = ""; errorBox.innerHTML = "";
errorBox.style.display = "none"; errorBox.style.display = "none";
} }
const adminName = document.getElementById("admin_name").value.trim();
const adminEmail = document.getElementById("admin_email").value.trim();
const adminPassword = document.getElementById("admin_password").value;
const adminPassword2 = document.getElementById("admin_password2").value;
if (!adminName) {
errors.push("Admin User Name ist ein Pflichtfeld.");
}
if (!adminEmail) {
errors.push("Admin User E-Mail ist ein Pflichtfeld.");
} else if (!emailRegex.test(adminEmail)) {
errors.push("Bitte eine gültige Admin E-Mail-Adresse eingeben.");
}
if (!adminPassword) {
errors.push("Admin Passwort ist ein Pflichtfeld.");
}
if (!adminPassword2) {
errors.push("Bitte Admin Passwort bestätigen.");
}
if (adminPassword && adminPassword2 && adminPassword !== adminPassword2) {
errors.push("Die beiden Admin-Passwörter stimmen nicht überein.");
}
if (adminPassword && adminPassword.length < 8) {
errors.push("Das Admin Passwort muss mindestens 8 Zeichen lang sein.");
}
}); });
}); });
</script> </script>