Changes to the Inventarsystem Workflow to Reflekt the new workflow and have an according set of buttons. So this removed all metioning of the duplication function.
Release Inventarsystem / release-docker (push) Successful in 2m15s
Release Inventarsystem / release-docker (push) Successful in 2m15s
This commit is contained in:
+4
-202
@@ -3927,7 +3927,6 @@ def upload_admin():
|
||||
"""
|
||||
Upload page route for inventory items.
|
||||
Accessible to users with insert permission.
|
||||
Supports duplication by passing duplicate_from parameter.
|
||||
|
||||
Returns:
|
||||
flask.Response: Rendered template or redirect
|
||||
@@ -3940,54 +3939,9 @@ def upload_admin():
|
||||
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'))
|
||||
|
||||
# Check if this is a duplication request
|
||||
duplicate_from = request.args.get('duplicate_from')
|
||||
duplicate_flag = request.args.get('duplicate') # Check for sessionStorage-based duplication
|
||||
duplicate_data = None
|
||||
|
||||
# Handle the old method (duplicate_from parameter with item ID)
|
||||
if duplicate_from:
|
||||
try:
|
||||
original_item = it.get_item(duplicate_from)
|
||||
if original_item:
|
||||
duplicate_data = {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': original_item.get('Filter1', ''),
|
||||
'filter2': original_item.get('Filter2', ''),
|
||||
'filter3': original_item.get('Filter3', ''),
|
||||
'images': original_item.get('Images', []),
|
||||
'original_id': duplicate_from
|
||||
}
|
||||
# Copy all filter fields (Filter1_1 through Filter3_5)
|
||||
for i in range(1, 4): # Filter1, Filter2, Filter3
|
||||
for j in range(1, 6): # _1 through _5
|
||||
filter_key = f'Filter{i}_{j}'
|
||||
if filter_key in original_item:
|
||||
duplicate_data[f'filter{i}_{j}'] = original_item[filter_key]
|
||||
|
||||
flash('Element wird dupliziert. Bitte überprüfen Sie die Daten und passen Sie sie bei Bedarf an.', 'info')
|
||||
else:
|
||||
flash('Ursprungs-Element für Duplizierung nicht gefunden.', 'error')
|
||||
except Exception as e:
|
||||
app.logger.warning(f"Error loading item for duplication: {e}")
|
||||
flash('Fehler beim Laden der Duplizierungsdaten.', 'error')
|
||||
|
||||
# Handle the new method (sessionStorage-based duplication)
|
||||
elif duplicate_flag == 'true':
|
||||
# No server-side processing needed - JavaScript will handle sessionStorage data
|
||||
# Just indicate that duplication mode is active
|
||||
flash('Element wird dupliziert. Die Daten werden aus dem Session-Speicher geladen.', 'info')
|
||||
|
||||
return render_template(
|
||||
'upload_admin.html',
|
||||
username=session['username'],
|
||||
duplicate_data=duplicate_data,
|
||||
library_module_enabled=cfg.MODULES.is_enabled('library'),
|
||||
student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'),
|
||||
show_library_features=False,
|
||||
@@ -4014,46 +3968,9 @@ def library_admin():
|
||||
flash('Bibliotheks-Modul ist deaktiviert.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
|
||||
duplicate_from = request.args.get('duplicate_from')
|
||||
duplicate_flag = request.args.get('duplicate')
|
||||
duplicate_data = None
|
||||
|
||||
if duplicate_from:
|
||||
try:
|
||||
original_item = it.get_item(duplicate_from)
|
||||
if original_item:
|
||||
duplicate_data = {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': original_item.get('Filter1', ''),
|
||||
'filter2': original_item.get('Filter2', ''),
|
||||
'filter3': original_item.get('Filter3', ''),
|
||||
'images': original_item.get('Images', []),
|
||||
'original_id': duplicate_from
|
||||
}
|
||||
for i in range(1, 4):
|
||||
for j in range(1, 6):
|
||||
filter_key = f'Filter{i}_{j}'
|
||||
if filter_key in original_item:
|
||||
duplicate_data[f'filter{i}_{j}'] = original_item[filter_key]
|
||||
flash('Buch wird dupliziert. Bitte überprüfen Sie die Daten und passen Sie sie bei Bedarf an.', 'info')
|
||||
else:
|
||||
flash('Ursprungs-Element für Duplizierung nicht gefunden.', 'error')
|
||||
except Exception as e:
|
||||
app.logger.warning(f"Error loading item for duplication: {e}")
|
||||
flash('Fehler beim Laden der Duplizierungsdaten.', 'error')
|
||||
elif duplicate_flag == 'true':
|
||||
flash('Buch wird dupliziert. Die Daten werden aus dem Session-Speicher geladen.', 'info')
|
||||
|
||||
return render_template(
|
||||
'upload_admin.html',
|
||||
username=session['username'],
|
||||
duplicate_data=duplicate_data,
|
||||
library_module_enabled=cfg.MODULES.is_enabled('library'),
|
||||
student_cards_module_enabled=cfg.MODULES.is_enabled('student_cards'),
|
||||
show_library_features=True,
|
||||
@@ -5388,18 +5305,18 @@ def upload_item():
|
||||
individual_codes = []
|
||||
if individual_codes_raw:
|
||||
individual_codes = [c.strip() for c in str(individual_codes_raw).replace(',', '\n').splitlines() if c.strip()]
|
||||
|
||||
|
||||
|
||||
# Check if this is a duplication
|
||||
is_duplicating = request.form.get('is_duplicating') == 'true'
|
||||
|
||||
|
||||
# Get duplicate_images if duplicating
|
||||
duplicate_images = request.form.getlist('duplicate_images') if is_duplicating else []
|
||||
|
||||
|
||||
# Make sure duplicate_images is always a list, even if there's only one
|
||||
if is_duplicating and duplicate_images and not isinstance(duplicate_images, list):
|
||||
duplicate_images = [duplicate_images]
|
||||
|
||||
|
||||
# Log details about each image
|
||||
if is_duplicating and duplicate_images:
|
||||
for i, img in enumerate(duplicate_images):
|
||||
@@ -5819,121 +5736,6 @@ def upload_item():
|
||||
flash(error_msg, 'error')
|
||||
return redirect(url_for(success_redirect_endpoint))
|
||||
|
||||
|
||||
@app.route('/duplicate_item', methods=['POST'])
|
||||
def duplicate_item():
|
||||
"""
|
||||
Route for duplicating an existing item.
|
||||
Returns JSON response with success status.
|
||||
Enhanced for mobile browser compatibility.
|
||||
|
||||
Returns:
|
||||
flask.Response: JSON response with success status and data
|
||||
"""
|
||||
try:
|
||||
# Check authentication
|
||||
if 'username' not in session:
|
||||
return jsonify({'success': False, 'message': 'Nicht angemeldet'}), 401
|
||||
|
||||
# Check if user is admin
|
||||
username = session['username']
|
||||
current_permissions = us.get_effective_permissions(session['username'])
|
||||
|
||||
if not current_permissions['actions'].get('can_edit', False):
|
||||
flash('Ihnen fehlen die nötigen Berechtigungen, um diese Aktion auszuführen.', 'error')
|
||||
return redirect(url_for('home_admin'))
|
||||
|
||||
# Detect if request is from mobile device
|
||||
is_mobile = 'Mobile' in request.headers.get('User-Agent', '')
|
||||
is_ios = 'iPhone' in request.headers.get('User-Agent', '') or 'iPad' in request.headers.get('User-Agent', '')
|
||||
|
||||
# Log mobile duplication for debugging
|
||||
if is_mobile:
|
||||
app.logger.info(f"Mobile duplication from {request.headers.get('User-Agent', 'unknown')} by {encrypt_text(username)}")
|
||||
|
||||
# Get original item ID
|
||||
original_item_id = request.form.get('original_item_id')
|
||||
if not original_item_id:
|
||||
return jsonify({'success': False, 'message': 'Ursprungs-Element-ID fehlt'}), 400
|
||||
|
||||
# Fetch original item data
|
||||
original_item = it.get_item(original_item_id)
|
||||
if not original_item:
|
||||
return jsonify({'success': False, 'message': 'Ursprungs-Element nicht gefunden'}), 404
|
||||
|
||||
# Process filters as arrays (same as stored in database)
|
||||
filter1_array = original_item.get('Filter', [])
|
||||
filter2_array = original_item.get('Filter2', [])
|
||||
filter3_array = original_item.get('Filter3', [])
|
||||
|
||||
# Ensure filters are arrays
|
||||
if not isinstance(filter1_array, list):
|
||||
filter1_array = [filter1_array] if filter1_array else []
|
||||
if not isinstance(filter2_array, list):
|
||||
filter2_array = [filter2_array] if filter2_array else []
|
||||
if not isinstance(filter3_array, list):
|
||||
filter3_array = [filter3_array] if filter3_array else []
|
||||
|
||||
# Verify image paths for mobile devices to avoid issues with non-existent images
|
||||
images = original_item.get('Images', [])
|
||||
verified_images = []
|
||||
|
||||
if is_mobile:
|
||||
for img in images:
|
||||
img_path = os.path.join(app.config['UPLOAD_FOLDER'], img)
|
||||
if os.path.exists(img_path) and os.path.isfile(img_path):
|
||||
verified_images.append(img)
|
||||
else:
|
||||
app.logger.warning(f"Image not found for duplication: {img}")
|
||||
|
||||
# If we lost images in verification, log it
|
||||
if len(verified_images) < len(images):
|
||||
app.logger.warning(f"Only {len(verified_images)} of {len(images)} images verified for mobile duplication")
|
||||
else:
|
||||
verified_images = images
|
||||
|
||||
# For iOS devices, add more diagnostics and reduce data size if needed
|
||||
if is_ios:
|
||||
# Check if images exist (we now use main images as thumbnails)
|
||||
images_exist = []
|
||||
for img in verified_images[:5]: # Only check first 5 to save time
|
||||
img_path = os.path.join(app.config['UPLOAD_FOLDER'], img)
|
||||
if os.path.exists(img_path):
|
||||
images_exist.append(True)
|
||||
else:
|
||||
images_exist.append(False)
|
||||
|
||||
# Log detailed diagnostics
|
||||
app.logger.info(f"iOS duplication details: {len(verified_images)} images, "
|
||||
f"images available: {all(images_exist)}, "
|
||||
f"filter sizes: {len(filter1_array)}, {len(filter2_array)}, {len(filter3_array)}")
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'message': 'Duplizierungsdaten erfolgreich vorbereitet',
|
||||
'item_data': {
|
||||
'name': original_item.get('Name', ''),
|
||||
'description': original_item.get('Beschreibung', ''),
|
||||
'location': original_item.get('Ort', ''),
|
||||
'room': original_item.get('Raum', ''),
|
||||
'category': original_item.get('Kategorie', ''),
|
||||
'year': original_item.get('Anschaffungsjahr', ''),
|
||||
'cost': original_item.get('Anschaffungskosten', ''),
|
||||
'filter1': filter1_array,
|
||||
'filter2': filter2_array,
|
||||
'filter3': filter3_array,
|
||||
'images': verified_images, # Using verified images instead of original
|
||||
'isMobile': is_mobile,
|
||||
'isIOS': is_ios
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in duplicate_item: {e}")
|
||||
|
||||
return jsonify({'success': False, 'message': 'Serverfehler beim Duplizieren'}), 500
|
||||
|
||||
|
||||
def _soft_delete_item_groups(db, root_item_ids, username):
|
||||
"""Soft-delete one or more item groups and their borrow records."""
|
||||
now = datetime.datetime.now()
|
||||
|
||||
Reference in New Issue
Block a user