From e46ee80cf2bb4d47885ff06e9ba849cd63f84200 Mon Sep 17 00:00:00 2001 From: AIIrondev Date: Fri, 21 Aug 2026 13:51:16 +0200 Subject: [PATCH] feat(library): add damage history view alongside invoices for items --- Web/app.py | 79 +++++++++++++++++++++++- Web/templates/library_item_invoices.html | 63 +++++++++++++++++-- 2 files changed, 135 insertions(+), 7 deletions(-) diff --git a/Web/app.py b/Web/app.py index f9d9da4..b4c06c0 100755 --- a/Web/app.py +++ b/Web/app.py @@ -9335,9 +9335,10 @@ def resolve_repaired_item_funct(item_id, action, new_code_4="", current_user="ad print(f"Error resolving repair for item {item_id}: {e}") return False, "Ein Datenbankfehler ist aufgetreten." + @app.route('/admin/library/items//invoices', methods=['GET']) def library_item_invoices(item_id): - """Show all stored invoices for one specific library item.""" + """Show all stored invoices and damages for one specific library item.""" if 'username' not in session: flash( 'Ihnen ist es nicht gestattet auf dieser Internetanwendung, die eben besuchte Adrrese zu nutzen, versuchen sie es erneut nach dem sie sich mit einem berechtigten Nutzer angemeldet haben!', @@ -9373,6 +9374,9 @@ def library_item_invoices(item_id): item_id_obj = item_doc.get('_id') item_id_str = str(item_id_obj) + # ========================================== + # 1. RECHNUNGSHISTORIE (Bestehender Code) + # ========================================== borrow_docs = list(ausleihungen.find( { 'Item': {'$in': [item_id_str, item_id_obj]}, @@ -9419,6 +9423,74 @@ def library_item_invoices(item_id): 'invoice_paid_by': invoice_data.get('paid_by', ''), }) + # ========================================== + # 2. SCHADENSHISTORIE (Neuer Code) + # ========================================== + raw_damages = [] + + # A: Schäden, die manuell am Element (Item-Dokument) hinterlegt wurden + item_damages = item_doc.get('Damages', []) + if not isinstance(item_damages, list): item_damages = [] + # Fallback falls sie klein geschrieben wurden + if isinstance(item_doc.get('damages', []), list): + item_damages.extend(item_doc.get('damages', [])) + + for d in item_damages: + if not isinstance(d, dict): continue + raw_damages.append({ + 'raw_date': d.get('date') or d.get('created_at'), + 'source': 'Manuell / Element', + 'user': d.get('reported_by') or d.get('user') or 'System/Admin', + 'description': d.get('description') or d.get('reason') or 'Keine Beschreibung', + 'status': d.get('status', 'Unbekannt'), + 'borrow_id': None + }) + + # B: Schäden, die in Ausleih-Dokumenten vermerkt sind + damage_borrow_docs = list(ausleihungen.find( + { + 'Item': {'$in': [item_id_str, item_id_obj]}, + '$or': [ + {'Damage': {'$exists': True, '$ne': ''}}, + {'DamageData': {'$exists': True, '$ne': {}}}, + {'Condition': {'$exists': True, '$ne': ''}} # Falls Zustand gemeldet wurde + ] + } + )) + + for b in damage_borrow_docs: + borrow_user = decrypt_text(b.get('User', '')) if b.get('User') else '—' + + d_data = b.get('DamageData') or {} + if not isinstance(d_data, dict): d_data = {} + + desc = d_data.get('description') or b.get('Damage') or b.get('Condition') + + if desc and str(desc).strip(): + raw_damages.append({ + 'raw_date': d_data.get('reported_at') or b.get('End') or b.get('Start'), + 'source': f"Ausleihe", + 'user': borrow_user, + 'description': desc, + 'status': d_data.get('status', 'Gemeldet'), + 'borrow_id': str(b.get('_id')) + }) + + # Daten chronologisch (neueste zuerst) sortieren + def get_sort_key(entry): + d = entry['raw_date'] + return d if isinstance(d, datetime.datetime) else datetime.datetime.min + + raw_damages.sort(key=get_sort_key, reverse=True) + + # Datums-Objekte für das Template formatieren + damage_entries = [] + for entry in raw_damages: + d_date = entry.pop('raw_date') + entry['date'] = d_date.strftime('%d.%m.%Y %H:%M') if isinstance(d_date, datetime.datetime) else str( + d_date or 'Unbekannt') + damage_entries.append(entry) + return render_template( 'library_item_invoices.html', item={ @@ -9429,14 +9501,15 @@ def library_item_invoices(item_id): 'isbn': item_doc.get('ISBN', ''), }, invoices=entries, + damages=damage_entries, # << NEU library_module_enabled=cfg.MODULES.is_enabled('library'), student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'), mail_module_enabled=cfg.MODULES.is_enabled('mail') ) except Exception as e: - app.logger.error(f"Error loading invoice history for item {item_id}: {e}") - flash('Fehler beim Laden der Rechnungshistorie.', 'error') + app.logger.error(f"Error loading invoice/damage history for item {item_id}: {e}") + flash('Fehler beim Laden der Rechnungs- oder Schadenshistorie.', 'error') return redirect(url_for('library_loans_admin')) finally: if client: diff --git a/Web/templates/library_item_invoices.html b/Web/templates/library_item_invoices.html index d12e922..8a95581 100644 --- a/Web/templates/library_item_invoices.html +++ b/Web/templates/library_item_invoices.html @@ -1,6 +1,6 @@ {% extends "base.html" %} -{% block title %}Rechnungen Element - {{ APP_VERSION }}{% endblock %} +{% block title %}Rechnungs- & Schadenshistorie - {{ APP_VERSION }}{% endblock %} {% block content %}