Implementation of an automatic code generation and generation of an excel.
Release Inventarsystem / release-docker (push) Successful in 2m14s

This commit is contained in:
2026-08-17 12:18:19 +02:00
parent 9ea0ae6157
commit 140fb5f743
2 changed files with 31 additions and 15 deletions
+30 -14
View File
@@ -2102,6 +2102,20 @@ def _build_student_card_excel_id(student_name, class_name, row_number, used_ids)
return candidate
def generate_ausweis_id_excel(existing_ids_set):
"""Generates a unique ID and checks against DB and current import queue."""
while True:
random_digits = "".join(random.choices(string.digits, k=6))
new_id = f"ID_{random_digits}"
# Prüfe sowohl in den bereits in dieser Session generierten IDs als auch in der DB
if new_id.upper() not in existing_ids_set and not us.get_user_by_student_card(new_id):
print(f"Generated unique ID: {new_id}")
return new_id
else:
print(f"Already found: {new_id}, trying another...")
def _upload_student_cards_excel():
"""Bulk import student cards from Excel with automatic name/class mapping."""
if 'username' not in session:
@@ -2142,12 +2156,12 @@ def _upload_student_cards_excel():
synonyms = {
'ausweis_id': ['ausweis_id', 'ausweisid', 'ausweis-id', 'karte', 'kartennummer', 'card_id', 'id'],
'student_name': ['student_name', 'schuelername', 'schülername', 'schueler', 'schüler', 'name', 'vollname', 'vorname_nachname', 'nachname_vorname'],
'first_name': ['vorname', 'first_name', 'firstname', 'rufname'],
'last_name': ['nachname', 'last_name', 'lastname'],
'class_name': ['klasse', 'class', 'class_name', 'jahrgang', 'jahrgangsstufe', 'stufe', 'gruppe', 'asv_klasse'],
'notes': ['notizen', 'notes', 'bemerkungen', 'bemerkung', 'hinweis', 'hinweise'],
'default_borrow_days': ['standard_ausleihdauer', 'ausleihdauer', 'borrow_days', 'tage', 'leihtage', 'max_borrow_days'],
'default_borrow_days': ['standard_ausleihdauer', 'ausleihdauer', 'borrow_days', 'tage', 'leihtage',
'max_borrow_days'],
}
def col_index(key):
@@ -2159,7 +2173,6 @@ def _upload_student_cards_excel():
mapped_indices = {
'ausweis_id': col_index('ausweis_id'),
'student_name': col_index('student_name'),
'first_name': col_index('first_name'),
'last_name': col_index('last_name'),
'class_name': col_index('class_name'),
@@ -2178,10 +2191,11 @@ def _upload_student_cards_excel():
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
try:
db = client[cfg.MONGODB_DB]
student_cards = list(db['student_cards'].find())
student_cards_cursor = db['student_cards'].find({}, {'AusweisId': 1})
existing_ids.update(
str(card.get('AusweisId', '')).strip().upper()
for card in student_cards.find({}, {'AusweisId': 1})
for card in student_cards_cursor
if card.get('AusweisId')
)
@@ -2199,27 +2213,29 @@ def _upload_student_cards_excel():
return row_values[idx]
ausweis_id = sanitize_form_value(val('ausweis_id'))
student_name = sanitize_form_value(val('student_name'))
first_name = sanitize_form_value(val('first_name'))
last_name = sanitize_form_value(val('last_name'))
class_name = sanitize_form_value(val('class_name'))
notes = sanitize_form_value(val('notes'))
default_borrow_days = _excel_int(val('default_borrow_days')) or cfg.STUDENT_DEFAULT_BORROW_DAYS
if not student_name and first_name and last_name:
student_name = f'{first_name} {last_name}'.strip()
validation_warnings.append((row_number, 'Schülername wurde aus Vorname und Nachname zusammengesetzt'))
default_borrow_days = _excel_int(val('default_borrow_days'))
if not default_borrow_days:
default_borrow_days = 14
first_name = sanitize_form_value(val('first_name')) or ""
last_name = sanitize_form_value(val('last_name')) or ""
student_name = f"{first_name} {last_name}".strip()
if not ausweis_id and not student_name and not class_name:
continue
row_errors = []
if not student_name:
row_errors.append('Schülername fehlt')
row_errors.append('Vorname und Nachname fehlen')
if not ausweis_id and student_name:
ausweis_id = _build_student_card_excel_id(student_name, class_name, row_number, existing_ids)
ausweis_id = generate_ausweis_id_excel(existing_ids)
validation_warnings.append((row_number, f'Ausweis-ID wurde automatisch erzeugt: {ausweis_id}'))
existing_ids.add(ausweis_id.upper())
elif ausweis_id:
ausweis_id = str(ausweis_id).strip().upper()
if ausweis_id in existing_ids:
+1 -1
View File
@@ -249,7 +249,7 @@
<div style="border:1px solid #dbe4ee; border-radius:8px; padding:14px; margin-bottom:16px; background:#f8fbff;">
<h3 style="margin:0 0 8px 0;">Excel-Import Bibliotheksausweise</h3>
<p style="margin:0 0 10px 0; color:#555;">Laden Sie eine <strong>.xlsx</strong>- oder <strong>.csv</strong>-Datei hoch, zum Beispiel aus <strong>ASV (Amtliche Schuldaten)</strong>. Erkannt werden automatisch Spalten wie <strong>Name</strong>, <strong>Klasse</strong>, <strong>Ausweis-ID</strong>, <strong>Notizen</strong> und <strong>Standard-Ausleihdauer</strong>. Fehlt die Ausweis-ID, wird sie automatisch aus Name und Klasse erzeugt.</p>
<p style="margin:0 0 10px 0; color:#555;">Laden Sie eine <strong>.xlsx</strong>- oder <strong>.csv</strong>-Datei hoch, zum Beispiel aus <strong>ASV (Amtliche Schuldaten)</strong>. Erkannt werden automatisch Spalten wie <strong>Name</strong>, <strong>Nachname</strong, <strong>Klasse</strong>, <strong>Ausweis-ID (optional)</strong>, <strong>Notizen (optional)</strong> und <strong>Standard-Ausleihdauer (optional)</strong>.</p>
<form method="POST" action="{{ url_for('upload_student_cards_excel') }}" enctype="multipart/form-data" style="display:flex; gap:10px; flex-wrap:wrap; align-items:center;">
<input type="file" name="student_cards_excel" accept=".xlsx,.csv" required>
<button type="submit" class="btn btn-secondary" name="excel_action" value="validate">Nur validieren</button>