From dd3d8649a742e0b9f0a057d714e4373162c2ec9f Mon Sep 17 00:00:00 2001 From: AIIrondev Date: Wed, 12 Aug 2026 11:37:05 +0200 Subject: [PATCH] fix of the template name --- Web/app.py | 167 ++--- Web/templates/edit_inventar.html | 1029 ++++++++++++++++++++++++++++++ Web/templates/edit_library.html | 1019 ++++++++--------------------- 3 files changed, 1372 insertions(+), 843 deletions(-) create mode 100644 Web/templates/edit_inventar.html diff --git a/Web/app.py b/Web/app.py index cb4cd44..888027f 100755 --- a/Web/app.py +++ b/Web/app.py @@ -6370,7 +6370,7 @@ def edit_item(id): @app.route('/item_edit/', methods=['GET', 'POST']) def item_edit(id): """ - Endpoint zum Laden und Aktualisieren eines Eintrags (item_edit). + Endpoint zum Bearbeiten von Artikeln (unterstützt Bibliotheks- und Inventar-Modus). """ if 'username' not in session: if request.method == 'POST' and request.is_json: @@ -6391,7 +6391,9 @@ def item_edit(id): flash('Ungültige Element-ID.', 'error') return redirect(url_for('home_admin')) - # --- GET: Template anzeigen --- + show_library = cfg.MODULES.is_enabled('library') + + # --- GET: Bearbeitungsformular laden --- if request.method == 'GET': item = it.get_item(id) if not item: @@ -6400,12 +6402,10 @@ def item_edit(id): item['_id'] = str(item['_id']) - # Codes für die Ansicht trennen (Basis-Code vs. Einzelcodes) + # Gruppen-Codes aufteilen (Basis-Code vs. Einzelcodes für die Textarea) base_code = item.get('Code_4', '') individual_codes = [] - - group_id = item.get('SeriesGroupId') - if group_id: + if item.get('SeriesGroupId'): group_ids = it.get_group_item_ids(str(item['_id'])) if group_ids: for gid in group_ids: @@ -6415,18 +6415,17 @@ def item_edit(id): individual_codes.append(c4) item['IndividualCodes'] = '\n'.join(individual_codes) - show_library = cfg.MODULES.is_enabled('library') return render_template( 'edit_library.html', username=session['username'], item=item, - library_module_enabled=show_library, show_library_features=show_library, + library_module_enabled=show_library, page_title=f"Bearbeiten: {item.get('Name', '')}" ) - # --- POST: Speichern --- + # --- POST: Änderungen speichern --- redirect_target = request.referrer or url_for('home_admin') current_item = it.get_item(obj_id) @@ -6434,12 +6433,15 @@ def item_edit(id): flash('Element in der Datenbank nicht gefunden.', 'error') return redirect(redirect_target) - # Formulardaten auslesen + # Gemeinsame Felder auslesen & bereinigen name = sanitize_form_value(request.form.get('name')) ort = sanitize_form_value(request.form.get('ort')) beschreibung = sanitize_form_value(request.form.get('beschreibung')) + anschaffungs_jahr = sanitize_form_value(request.form.get('anschaffungsjahr')) + anschaffungs_kosten = sanitize_form_value(request.form.get('anschaffungskosten')) + reservierbar = 'reservierbar' in request.form - # Basis-Code & Einzelcodes aus der Textarea + # Barcode & Gruppen-Codes code_4 = sanitize_form_value(request.form.get('code_4')) individual_codes_raw = request.form.get('individual_codes', '') @@ -6451,74 +6453,12 @@ def item_edit(id): all_codes_to_check = [code_4] + individual_codes - isbn_raw = sanitize_form_value(request.form.get('isbn', '')) - anschaffungs_jahr = sanitize_form_value(request.form.get('anschaffungsjahr')) - anschaffungs_kosten = sanitize_form_value(request.form.get('anschaffungskosten')) - reservierbar = 'reservierbar' in request.form - - item_type_input = sanitize_form_value(request.form.get('item_type_input')) - library_category = sanitize_form_value(request.form.get('library_category')) - - filter1 = expand_filter_selection(sanitize_form_value(request.form.getlist('filter')), 1) - filter2 = expand_filter_selection(sanitize_form_value(request.form.getlist('filter2')), 2) - filter3 = sanitize_form_value(request.form.getlist('filter3')) - - verfuegbar = current_item.get('Verfuegbar', True) - - # Uniqueness-Check über alle Codes + # Uniqueness-Check für alle übergebenen Barcodes current_group_id = current_item.get('SeriesGroupId') client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT) db_instance = client[cfg.MONGODB_DB] items_col = db_instance['items'] - # Bilder verarbeiten (GridFS) - images_to_keep = request.form.getlist('existing_images') - original_images = current_item.get('Images', []) - images = [img for img in original_images if img in images_to_keep] - - new_files = request.files.getlist('images') - if new_files and new_files[0].filename != '': - fs = get_gridfs() - for file in new_files: - if file and file.filename: - is_allowed, error_msg = allowed_file(file.filename, file) - if not is_allowed: - flash(error_msg, 'error') - return redirect(redirect_target) - - try: - secure_name = secure_filename(file.filename) - file.seek(0) - image_bytes = file.read() - - if not image_bytes: - continue - - optimized_io = io.BytesIO() - with Image.open(io.BytesIO(image_bytes)) as img: - if img.mode not in ('RGB', 'RGBA'): - img = img.convert('RGBA') - - max_width = 800 - if img.width > max_width: - ratio = max_width / img.width - img = img.resize((max_width, int(img.height * ratio)), Image.Resampling.LANCZOS) - - img.save(optimized_io, format='WEBP', quality=85, optimize=True) - - optimized_io.seek(0) - new_filename = f"{uuid.uuid4().hex}_{int(time.time())}.webp" - - fs.put( - optimized_io, - filename=new_filename, - content_type='image/webp', - metadata={'original_filename': secure_name, 'item_id': str(id)} - ) - images.append(new_filename) - except Exception as e: - app.logger.error(f"Bild-Fehler bei Item {id}: {e}") - has_code_error = False for code in all_codes_to_check: if not code: @@ -6536,17 +6476,84 @@ def item_edit(id): if has_code_error: return redirect(redirect_target) - # 1. Gruppen-Bestand über die korrigierte Helfer-Funktion synchronisieren + # --- Modi-spezifische Auswertung --- + if show_library: + # 1. Bibliotheks-Modus + isbn_raw = sanitize_form_value(request.form.get('isbn', '')) + item_isbn = normalize_and_validate_isbn(isbn_raw) if isbn_raw else '' + item_type = sanitize_form_value(request.form.get('item_type_input', 'Buch')) + library_category = sanitize_form_value(request.form.get('library_category', '')) + + filter1 = current_item.get('Filter', []) + filter2 = current_item.get('Filter2', []) + filter3 = current_item.get('Filter3', []) + images = current_item.get('Images', []) + else: + # 2. Inventar-Modus + item_isbn = current_item.get('ISBN', '') + item_type = current_item.get('ItemType', 'other') + library_category = current_item.get('library_category', '') + + filter1 = expand_filter_selection(sanitize_form_value(request.form.getlist('filter')), 1) + filter2 = expand_filter_selection(sanitize_form_value(request.form.getlist('filter2')), 2) + filter3 = sanitize_form_value(request.form.getlist('filter3')) + + # Bilderverarbeitung für den Inventar-Modus + images_to_keep = request.form.getlist('existing_images') + original_images = current_item.get('Images', []) + images = [img for img in original_images if img in images_to_keep] + + new_files = request.files.getlist('images') + if new_files and new_files[0].filename != '': + fs = get_gridfs() + for file in new_files: + if file and file.filename: + is_allowed, error_msg = allowed_file(file.filename, file) + if not is_allowed: + flash(error_msg, 'error') + return redirect(redirect_target) + try: + secure_name = secure_filename(file.filename) + file.seek(0) + image_bytes = file.read() + if not image_bytes: + continue + optimized_io = io.BytesIO() + with Image.open(io.BytesIO(image_bytes)) as img: + if img.mode not in ('RGB', 'RGBA'): + img = img.convert('RGBA') + max_width = 800 + if img.width > max_width: + ratio = max_width / img.width + img = img.resize((max_width, int(img.height * ratio)), Image.Resampling.LANCZOS) + img.save(optimized_io, format='WEBP', quality=85, optimize=True) + optimized_io.seek(0) + new_filename = f"{uuid.uuid4().hex}_{int(time.time())}.webp" + fs.put( + optimized_io, + filename=new_filename, + content_type='image/webp', + metadata={'original_filename': secure_name, 'item_id': str(id)} + ) + images.append(new_filename) + except Exception as e: + app.logger.error(f"Bild-Fehler bei Item {id}: {e}") + + # Standort bei Bedarf zu vordefinierten Orten hinzufügen + if ort and ort not in it.get_predefined_locations(): + it.add_predefined_location(ort) + + # 1. Gruppen-Codes synchronisieren it.sync_group_codes(str(id), code_4, individual_codes) - # 2. Deine bestehende update_item Funktion aufrufen + # 2. Datenbank-Eintrag aktualisieren success = it.update_item( id=str(id), name=name, ort=ort, beschreibung=beschreibung, images=images, - verfuegbar=verfuegbar, + verfuegbar=current_item.get('Verfuegbar', True), filter1=filter1, filter2=filter2, filter3=filter3, @@ -6554,8 +6561,9 @@ def item_edit(id): ansch_kost=anschaffungs_kosten, code_4=code_4, reservierbar=reservierbar, - isbn=isbn_raw, - item_type=item_type_input + isbn=item_isbn, + item_type=item_type, + library_category=library_category ) if success: @@ -6564,7 +6572,6 @@ def item_edit(id): flash('Fehler beim Aktualisieren des Artikels.', 'error') return redirect(redirect_target) - @app.route('/update_group', methods=['POST']) def update_group(): diff --git a/Web/templates/edit_inventar.html b/Web/templates/edit_inventar.html new file mode 100644 index 0000000..2e20b48 --- /dev/null +++ b/Web/templates/edit_inventar.html @@ -0,0 +1,1029 @@ + +{% extends "base.html" %} + +{% block title %}{{ page_title|default('Artikel bearbeiten') }} - Inventarsystem{% endblock %} + +{% block content %} + + + + + +
+
+

{{ page_title|default('Artikel bearbeiten') }}

+ +
+ + + + + {% if show_library_features %} + +
+ +
+ + + +
+ + +
+
+ {% endif %} + + +
+ + +
+ + +
+ + + + +
+ + +
+ + +
+ + +
+ +
+ + +
+ + +
+ + +
+ + + Der Scanner füllt zuerst den Basis-Code; weitere gescannte Codes werden hier automatisch zeilenweise angehängt. +
+ + {% if show_library_features %} + +
+

Medientyp

+
+ {% set current_type = item.ItemType if item.ItemType else '' %} + +
+ +

Kategorie / Fach:

+
+ +
+
+ {% else %} + +
+

Unterrichtsfach:

+
+ {% for i in range(1, 5) %} +
+ + +
+ {% endfor %} +
+ +

Jahrgangsstufe:

+
+ {% for i in range(1, 5) %} +
+ + +
+ {% endfor %} +
+ +

Schlagwörter:

+
+ {% for i in range(1, 5) %} +
+ + +
+ {% endfor %} +
+
+ {% endif %} + + +
+ + +
+ +
+ + +
+ + +
+ +
+ {% if item.Images %} + {% for img in item.Images %} +
+ + +
+ {% endfor %} + {% else %} + Keine Bilder vorhanden. + {% endif %} +
+ + + +
+
+ + +
+ + +
+ + +
+
+
+ + + + +{% endblock %} \ No newline at end of file diff --git a/Web/templates/edit_library.html b/Web/templates/edit_library.html index 2e20b48..b652ab2 100644 --- a/Web/templates/edit_library.html +++ b/Web/templates/edit_library.html @@ -1,395 +1,14 @@ {% extends "base.html" %} {% block title %}{{ page_title|default('Artikel bearbeiten') }} - Inventarsystem{% endblock %} {% block content %} - - -

{{ page_title|default('Artikel bearbeiten') }}

- -
- + - {% if show_library_features %} - +
- -
- - - + +
+ + +
- -
+ +
{% endif %} - +
- +
- +
- + {% if item.Ort %} + + {% endif %} - - - +
- +
- - + +
- +
- - - Der Scanner füllt zuerst den Basis-Code; weitere gescannte Codes werden hier automatisch zeilenweise angehängt. + + + Der Basis-Code steht oben. Alle weiteren Gruppenmitglieder werden hier untereinander aufgeführt.
{% if show_library_features %} - +

Medientyp

- {% set current_type = item.ItemType if item.ItemType else '' %} - + + + + +
-

Kategorie / Fach:

- +
{% else %} - +
-

Unterrichtsfach:

+

Unterrichtsfach (Filter 1):

- {% for i in range(1, 5) %} + {% for idx in range(4) %}
- - +
{% endfor %}
-

Jahrgangsstufe:

+

Jahrgangsstufe (Filter 2):

- {% for i in range(1, 5) %} + {% for idx in range(4) %}
- - +
{% endfor %}
-

Schlagwörter:

+

Schlagwort (Filter 3):

- {% for i in range(1, 5) %} + {% for idx in range(4) %}
- - + +
{% endfor %}
{% endif %} - +
- +
-
- +
- + {% if not show_library_features %} +
- -
- {% if item.Images %} - {% for img in item.Images %} -
- - -
- {% endfor %} - {% else %} - Keine Bilder vorhanden. - {% endif %} + + {% if item.Images and item.Images|length > 0 %} +
+ {% for img in item.Images %} +
+ Bild + +
+ {% endfor %}
+ {% else %} +

Keine Bilder vorhanden.

+ {% endif %} - - -
+ +
+ {% endif %} - +
- +
- +
- {% endblock %} \ No newline at end of file