Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a51c4c4cbe | |||
| e4b27c2d62 | |||
| bf85d406ac | |||
| 06e0c6dfb7 | |||
| fc25c2cd90 | |||
| c672ffcb12 | |||
| 2bafc55e00 | |||
| 7e20790bac | |||
| 3aa065d039 | |||
| 56d79610aa |
+83
-36
@@ -93,6 +93,7 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
import Web.modules.database.settings as cfg
|
||||
from Web.modules.database.settings import MongoClient
|
||||
from tenant import get_tenant_context, get_tenant_db, get_tenant_trial_status, purge_expired_trial_tenants
|
||||
from pymongo.errors import DuplicateKeyError
|
||||
|
||||
|
||||
app = Flask(__name__, static_folder='static') # Correctly set static folder
|
||||
@@ -8759,11 +8760,13 @@ def admin_create_invoice(borrow_id):
|
||||
def admin_mark_invoice_paid(borrow_id):
|
||||
"""Mark an existing invoice as paid."""
|
||||
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!', 'error')
|
||||
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!',
|
||||
'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
|
||||
|
||||
if not current_permissions['pages'].get('admin_borrowings', False):
|
||||
flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
@@ -8829,25 +8832,25 @@ def admin_mark_invoice_paid(borrow_id):
|
||||
)
|
||||
|
||||
flash('Rechnung wurde als bezahlt markiert.', 'success')
|
||||
return redirect(url_for('admin_borrowings'))
|
||||
return redirect(url_for('library_loans_admin'))
|
||||
except Exception as e:
|
||||
app.logger.error(f"Error marking invoice paid for borrow {borrow_id}: {e}")
|
||||
flash('Fehler beim Markieren als bezahlt.', 'error')
|
||||
return redirect(url_for('admin_borrowings'))
|
||||
return redirect(url_for('library_loans_admin'))
|
||||
finally:
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
|
||||
@app.route('/admin/borrowings/<borrow_id>/invoice/pay', methods=['POST'])
|
||||
def admin_mark_invoice_paid(borrow_id):
|
||||
"""Mark invoice as paid."""
|
||||
def admin_pay_invoice_extended(borrow_id):
|
||||
"""Mark invoice as paid and complete borrowing if active."""
|
||||
if 'username' not in session:
|
||||
flash('Ihnen ist es nicht gestattet, versuchen sie es erneut nach Anmeldung!', 'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
if not current_permissions['pages'].get('admin_borrowings', False):
|
||||
if not current_permissions['pages'].get('library_loans_admin', False):
|
||||
flash('Ihnen fehlen die nötigen Berechtigungen.', 'error')
|
||||
return redirect(request.referrer or url_for('home_admin'))
|
||||
|
||||
@@ -8860,17 +8863,16 @@ def admin_mark_invoice_paid(borrow_id):
|
||||
borrow_doc = ausleihungen.find_one({'_id': ObjectId(borrow_id)})
|
||||
if not borrow_doc:
|
||||
flash('Ausleihung nicht gefunden.', 'error')
|
||||
return redirect(request.referrer or url_for('admin_borrowings'))
|
||||
return redirect(request.referrer or url_for('library_loans_admin'))
|
||||
|
||||
invoice_data = borrow_doc.get('InvoiceData') or {}
|
||||
if not invoice_data:
|
||||
flash('Für diese Ausleihung existiert keine Rechnung.', 'warning')
|
||||
return redirect(request.referrer or url_for('admin_borrowings'))
|
||||
return redirect(request.referrer or url_for('library_loans_admin'))
|
||||
|
||||
now = datetime.datetime.now()
|
||||
update_fields = {'LastUpdated': now}
|
||||
|
||||
# Rechnung auf bezahlt setzen
|
||||
if invoice_data.get('paid') is not True:
|
||||
update_fields.update({
|
||||
'InvoiceData.paid': True,
|
||||
@@ -8878,14 +8880,12 @@ def admin_mark_invoice_paid(borrow_id):
|
||||
'InvoiceData.paid_by': session.get('username', ''),
|
||||
})
|
||||
|
||||
# Ausleihe abschließen, falls noch aktiv
|
||||
if borrow_doc.get('Status') == 'active':
|
||||
update_fields['Status'] = 'completed'
|
||||
update_fields['End'] = now
|
||||
|
||||
ausleihungen.update_one({'_id': borrow_doc['_id']}, {'$set': update_fields})
|
||||
|
||||
# Logging
|
||||
try:
|
||||
db['system_logs'].insert_one({
|
||||
'type': 'invoice_paid',
|
||||
@@ -8918,9 +8918,8 @@ def admin_mark_invoice_paid(borrow_id):
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
|
||||
@app.route('/admin/items/<item_id>/repair', methods=['POST'])
|
||||
def mark_damage_repaired(item_id):
|
||||
def resolve_repaired_item(item_id):
|
||||
"""Mark item as repaired and make it available again."""
|
||||
if 'username' not in session:
|
||||
return redirect(url_for('login'))
|
||||
@@ -9121,11 +9120,37 @@ def admin_add_invoice_correction(borrow_id):
|
||||
if client:
|
||||
client.close()
|
||||
|
||||
@app.route('/admin/items/<item_id>/resolve_repair', methods=['POST'])
|
||||
def admin_resolve_repair(item_id):
|
||||
"""Flask-Route für die Reparatur-Aktionen (repair, replace, delete)."""
|
||||
if 'username' not in session:
|
||||
flash('Bitte melden Sie sich an, um fortzufahren.', 'error')
|
||||
return redirect(url_for('login'))
|
||||
|
||||
def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
if not current_permissions['pages'].get('library_loans_admin', False):
|
||||
flash('Ihnen fehlen die nötigen Berechtigungen für diese Aktion.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
|
||||
action = request.form.get('action', 'repair')
|
||||
new_code_4 = request.form.get('new_code_4', '')
|
||||
current_user = session.get('username', 'admin')
|
||||
|
||||
success, message = resolve_repaired_item_funct(item_id, action, new_code_4, current_user)
|
||||
|
||||
if success:
|
||||
flash(message, 'success')
|
||||
else:
|
||||
flash(message, 'error')
|
||||
|
||||
return redirect(url_for('library_loans_admin'))
|
||||
|
||||
|
||||
def resolve_repaired_item_funct(item_id, action, new_code_4="", current_user="admin"):
|
||||
"""
|
||||
Verarbeitet Items aus der Reparatur und aktualisiert die Serien-Counts
|
||||
sowie Parent/Child-Abhängigkeiten beim Löschen korrekt.
|
||||
Entfernt Schadens-Flags komplett aus Items und zugehörigen Ausleihen.
|
||||
"""
|
||||
if not ObjectId.is_valid(item_id):
|
||||
return False, "Ungültige Item-ID."
|
||||
@@ -9135,12 +9160,25 @@ def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
db = client[cfg.MONGODB_DB]
|
||||
items = db['items']
|
||||
|
||||
borrowings = db['borrowings'] if 'borrowings' in db.list_collection_names() else None
|
||||
|
||||
item = items.find_one({'_id': ObjectId(item_id)})
|
||||
if not item:
|
||||
return False, "Item nicht in der Datenbank gefunden."
|
||||
|
||||
series_group_id = item.get('SeriesGroupId')
|
||||
|
||||
damage_unset = {
|
||||
'HasDamage': "",
|
||||
'has_damage': "",
|
||||
'DamageCount': "",
|
||||
'damage_count': "",
|
||||
'DamageText': "",
|
||||
'damage_text': "",
|
||||
'is_damaged': "",
|
||||
'IsDamaged': ""
|
||||
}
|
||||
|
||||
# --- OPTION 1: DELETE ---
|
||||
if action == 'delete':
|
||||
is_parent = not item.get('IsGroupedSubItem')
|
||||
@@ -9155,7 +9193,6 @@ def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
if sibling:
|
||||
new_parent_id_str = str(sibling['_id'])
|
||||
|
||||
# 1. Mache das Geschwister-Item zum neuen Parent
|
||||
items.update_one(
|
||||
{'_id': sibling['_id']},
|
||||
{'$set': {
|
||||
@@ -9164,7 +9201,6 @@ def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
}}
|
||||
)
|
||||
|
||||
# 2. Leite alle anderen verbleibenden Sub-Items auf den neuen Parent um
|
||||
items.update_many(
|
||||
{
|
||||
'SeriesGroupId': series_group_id,
|
||||
@@ -9173,17 +9209,8 @@ def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
{'$set': {'ParentItemId': new_parent_id_str}}
|
||||
)
|
||||
|
||||
# Physisch aus der Datenbank löschen (Hard Delete)
|
||||
items.delete_one({'_id': ObjectId(item_id)})
|
||||
|
||||
# ALTERNATIVE (Soft Delete have to see if it makes sense):
|
||||
# now = datetime.datetime.now()
|
||||
# items.update_one(
|
||||
# {'_id': ObjectId(item_id)},
|
||||
# {'$set': {'Deleted': True, 'DeletedAt': now, 'DeletedBy': current_user}}
|
||||
# )
|
||||
|
||||
# SeriesCount bei ALLEN verbleibenden Items dieser Serie um 1 reduzieren
|
||||
if series_group_id:
|
||||
items.update_many(
|
||||
{'SeriesGroupId': series_group_id},
|
||||
@@ -9196,23 +9223,43 @@ def resolve_repaired_item(item_id, action, new_code_4="", current_user="admin"):
|
||||
elif action == 'replace':
|
||||
items.update_one(
|
||||
{'_id': ObjectId(item_id)},
|
||||
{'$set': {
|
||||
'Code_4': str(new_code_4).strip(),
|
||||
'Verfuegbar': True,
|
||||
'LastUpdated': datetime.datetime.now()
|
||||
}}
|
||||
{
|
||||
'$set': {
|
||||
'Code_4': str(new_code_4).strip(),
|
||||
'Verfuegbar': True,
|
||||
'LastUpdated': datetime.datetime.now()
|
||||
},
|
||||
'$unset': damage_unset
|
||||
}
|
||||
)
|
||||
|
||||
if borrowings is not None:
|
||||
borrowings.update_many(
|
||||
{'$or': [{'item_id': str(item_id)}, {'item_id': ObjectId(item_id)}]},
|
||||
{'$unset': damage_unset}
|
||||
)
|
||||
|
||||
return True, f"Item wurde ersetzt. Neuer Code 4 zugewiesen: {new_code_4}."
|
||||
|
||||
# --- OPTION 3: JUST REPAIR ---
|
||||
elif action == 'repair':
|
||||
items.update_one(
|
||||
{'_id': ObjectId(item_id)},
|
||||
{'$set': {
|
||||
'Verfuegbar': True,
|
||||
'LastUpdated': datetime.datetime.now()
|
||||
}}
|
||||
{
|
||||
'$set': {
|
||||
'Verfuegbar': True,
|
||||
'LastUpdated': datetime.datetime.now()
|
||||
},
|
||||
'$unset': damage_unset
|
||||
}
|
||||
)
|
||||
|
||||
if borrowings is not None:
|
||||
borrowings.update_many(
|
||||
{'$or': [{'item_id': str(item_id)}, {'item_id': ObjectId(item_id)}]},
|
||||
{'$unset': damage_unset}
|
||||
)
|
||||
|
||||
return True, "Item wurde repariert und ist wieder regulär verfügbar."
|
||||
|
||||
else:
|
||||
@@ -9290,7 +9337,7 @@ def library_item_invoices(item_id):
|
||||
entries.append({
|
||||
'borrow_id': str(borrow_doc.get('_id')),
|
||||
'borrow_status': borrow_doc.get('Status', ''),
|
||||
'borrow_user': borrow_doc.get('User', ''),
|
||||
'borrow_user': decrypt_text(borrow_doc.get('User', '')),
|
||||
'borrow_start': borrow_doc.get('Start').strftime('%d.%m.%Y %H:%M') if isinstance(
|
||||
borrow_doc.get('Start'), datetime.datetime) else '',
|
||||
'borrow_end': borrow_doc.get('End').strftime('%d.%m.%Y %H:%M') if isinstance(borrow_doc.get('End'),
|
||||
|
||||
@@ -730,11 +730,11 @@ def get_user_by_student_ident(student_ident):
|
||||
return user_doc
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"Entschlüsselungsfehler bei ID {user_doc.get('_id')}: {e}")
|
||||
logger.error(f"Entschlüsselungsfehler bei ID {user_doc.get('_id')}: {e}")
|
||||
continue
|
||||
|
||||
except Exception as exc:
|
||||
app.logger.error(f"Datenbankfehler in get_user_by_student_ident: {exc}")
|
||||
logger.error(f"Datenbankfehler in get_user_by_student_ident: {exc}")
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user