Compare commits

...

5 Commits

Author SHA1 Message Date
Aiirondev_dev 6a3865ef24 fix of the template name
Release Inventarsystem / release-docker (push) Successful in 2m16s
2026-08-12 11:46:59 +02:00
Aiirondev_dev 96d45710ac fix of the template name
Release Inventarsystem / release-docker (push) Successful in 2m15s
2026-08-12 11:45:48 +02:00
Aiirondev_dev dd3d8649a7 fix of the template name
Release Inventarsystem / release-docker (push) Successful in 3m10s
2026-08-12 11:37:05 +02:00
Aiirondev_dev 1af2a2be06 implementation of the image
Release Inventarsystem / release-docker (push) Successful in 2m14s
2026-08-12 00:32:00 +02:00
Aiirondev_dev 8e5e434116 fix of the template name
Release Inventarsystem / release-docker (push) Successful in 2m15s
2026-08-12 00:24:25 +02:00
4 changed files with 1411 additions and 812 deletions
+119 -48
View File
@@ -6366,11 +6366,25 @@ def edit_item(id):
return redirect(url_for('home_admin'))
def is_library_item(item):
"""
Prüft, ob ein Artikel ein Bibliotheks-Item ist.
- 'other', None oder Leerstring -> Inventarsystem (False)
- Jeder andere Medientyp ('Buch', 'CD', etc.) -> Bibliothek (True)
"""
if not item:
return False
item_type = item.get('ItemType', 'other')
if not item_type:
return False
return item_type.strip().lower() != 'other'
@app.route('/item_edit/<id>', methods=['GET', 'POST'])
def item_edit(id):
"""
Endpoint zum Laden und Aktualisieren eines Eintrags (item_edit).
Complete endpoint for editing items. Automatically detects whether the item
is a Library item (ItemType != 'other') or an Inventory item (ItemType == 'other').
"""
if 'username' not in session:
if request.method == 'POST' and request.is_json:
@@ -6391,22 +6405,27 @@ def item_edit(id):
flash('Ungültige Element-ID.', 'error')
return redirect(url_for('home_admin'))
# --- GET: Template anzeigen ---
current_item = it.get_item(obj_id)
if not current_item:
flash('Element in der Datenbank nicht gefunden.', 'error')
return redirect(url_for('home_admin'))
# Determine item type classification
library_module_active = cfg.MODULES.is_enabled('library')
is_lib_item = it.is_library_item(current_item)
show_library_features = library_module_active and is_lib_item
# -------------------------------------------------------------------
# GET METHOD: Render Form
# -------------------------------------------------------------------
if request.method == 'GET':
item = it.get_item(id)
if not item:
flash('Element nicht gefunden.', 'error')
return redirect(url_for('home_admin'))
current_item['_id'] = str(current_item['_id'])
item['_id'] = str(item['_id'])
# Codes für die Ansicht trennen (Basis-Code vs. Einzelcodes)
base_code = item.get('Code_4', '')
# Format individual group codes for the textarea
base_code = current_item.get('Code_4', '')
individual_codes = []
group_id = item.get('SeriesGroupId')
if group_id:
group_ids = it.get_group_item_ids(str(item['_id']))
if current_item.get('SeriesGroupId'):
group_ids = it.get_group_item_ids(str(current_item['_id']))
if group_ids:
for gid in group_ids:
g_item = it.get_item(gid)
@@ -6414,32 +6433,31 @@ def item_edit(id):
if c4 and c4 != base_code:
individual_codes.append(c4)
item['IndividualCodes'] = '\n'.join(individual_codes)
show_library = cfg.MODULES.is_enabled('library')
current_item['IndividualCodes'] = '\n'.join(individual_codes)
return render_template(
'edit_library.html',
username=session['username'],
item=item,
library_module_enabled=show_library,
show_library_features=show_library,
page_title=f"Bearbeiten: {item.get('Name', '')}"
item=current_item,
show_library_features=show_library_features,
library_module_enabled=library_module_active,
page_title=f"Bearbeiten: {current_item.get('Name', '')}"
)
# --- POST: Speichern ---
# -------------------------------------------------------------------
# POST METHOD: Save Changes
# -------------------------------------------------------------------
redirect_target = request.referrer or url_for('home_admin')
current_item = it.get_item(obj_id)
if not current_item:
flash('Element in der Datenbank nicht gefunden.', 'error')
return redirect(redirect_target)
# Formulardaten auslesen
# Common fields
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
# Barcodes
code_4 = sanitize_form_value(request.form.get('code_4'))
individual_codes_raw = request.form.get('individual_codes', '')
@@ -6451,21 +6469,7 @@ 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
# Barcode uniqueness check
current_group_id = current_item.get('SeriesGroupId')
client = MongoClient(cfg.MONGODB_HOST, cfg.MONGODB_PORT)
db_instance = client[cfg.MONGODB_DB]
@@ -6488,17 +6492,84 @@ def item_edit(id):
if has_code_error:
return redirect(redirect_target)
# 1. Gruppen-Bestand über die korrigierte Helfer-Funktion synchronisieren
# Type-specific processing
if show_library_features:
# --- LIBRARY ITEM ---
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:
# --- INVENTORY ITEM ---
item_isbn = current_item.get('ISBN', '')
item_type = 'other' # Standard type for inventory items
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'))
# Manage images for Inventory Mode
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"Image error for item {id}: {e}")
# Auto-add new location to predefined locations list if applicable
if ort and ort not in it.get_predefined_locations():
it.add_predefined_location(ort)
# Sync series/group barcode IDs
it.sync_group_codes(str(id), code_4, individual_codes)
# 2. Deine bestehende update_item Funktion aufrufen
# Update item in database
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,
@@ -6507,7 +6578,8 @@ def item_edit(id):
code_4=code_4,
reservierbar=reservierbar,
isbn=item_isbn,
item_type=item_type
item_type=item_type,
library_category=library_category
)
if success:
@@ -6516,7 +6588,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():
+13
View File
@@ -27,6 +27,19 @@ from Web.modules.database.settings import MongoClient
import Web.modules.inventarsystem.data_protection as dp
def is_library_item(item):
"""
Determines if an item belongs to the library system.
Returns False for 'other', None, or empty ItemType (Inventory item).
Returns True for any specific library type ('Buch', 'CD', 'DVD', etc.).
"""
if not item:
return False
item_type = item.get('ItemType', 'other')
if not item_type:
return False
return str(item_type).strip().lower() != 'other'
def safe_decrypt_user(encrypted_user):
"""
Safely decrypt an encrypted username string.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff