feat(library): add damage history view alongside invoices for items
Release Inventarsystem / release-docker (push) Successful in 2m14s

This commit is contained in:
2026-08-21 13:51:16 +02:00
parent f0b112b34c
commit e46ee80cf2
2 changed files with 135 additions and 7 deletions
+76 -3
View File
@@ -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/<item_id>/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: