- Fix template rendering without BrandingConfig in some pages - Moved JS file to static/js/ subdirectory
139 lines
4.8 KiB
Python
139 lines
4.8 KiB
Python
from flask import Blueprint, request, render_template, redirect, session, flash
|
|
from definitions.models import Asset, db
|
|
from functions.process_csv import get_csv_data
|
|
from functions.validate_values import validate_values
|
|
from config import item_attributes
|
|
from functions.auth import login_required
|
|
from config import BrandingConfig
|
|
|
|
upload_bp = Blueprint('uploadcsv', __name__)
|
|
|
|
def _process_csv_file(file, mode):
|
|
"""
|
|
Helper function to process CSV file and separate entries based on mode.
|
|
mode: 'import' or 'edit'
|
|
"""
|
|
# Extract CSV data
|
|
csvdata = get_csv_data(file)
|
|
|
|
# Validate each row of data
|
|
errors = []
|
|
for i, row in enumerate(csvdata, start=1):
|
|
error = validate_values(row)
|
|
if error:
|
|
errors.append(f"Row {i}: {error}")
|
|
|
|
if errors:
|
|
return None, errors
|
|
|
|
# Separate entries based on mode
|
|
primary_attrib = next((attrib for attrib in item_attributes if attrib.primary), None)
|
|
if not primary_attrib:
|
|
return None, ["Primary attribute not defined in configuration."]
|
|
|
|
new_entries = []
|
|
existing_entries = []
|
|
invalid_entries = []
|
|
|
|
for row in csvdata:
|
|
primary_value = row[primary_attrib.attrib_name]
|
|
asset_exists = Asset.query.filter_by(**{primary_attrib.attrib_name: primary_value}).first()
|
|
|
|
if mode == 'import':
|
|
if asset_exists:
|
|
invalid_entries.append(row) # Existing entries are invalid for import
|
|
else:
|
|
new_entries.append(row)
|
|
elif mode == 'edit':
|
|
if asset_exists:
|
|
existing_entries.append(row) # Existing entries are valid for edit
|
|
else:
|
|
invalid_entries.append(row) # Non-existing entries are invalid for edit
|
|
|
|
return {
|
|
'new_entries': new_entries,
|
|
'existing_entries': existing_entries,
|
|
'invalid_entries': invalid_entries
|
|
}, None
|
|
|
|
@upload_bp.route('/import_from_csv/', methods=['GET', 'POST'])
|
|
@login_required
|
|
def import_from_csv():
|
|
session['csv_mode'] = 'import' # Store mode in session
|
|
if request.method == 'POST':
|
|
# Check if a file was uploaded
|
|
if 'file' not in request.files:
|
|
flash("No file uploaded.", "error")
|
|
return redirect(request.url)
|
|
|
|
file = request.files['file']
|
|
|
|
# Check if the file is a CSV
|
|
if file.filename == '' or not file.filename.endswith('.csv'):
|
|
flash("Please upload a valid CSV file.", "error")
|
|
return redirect(request.url)
|
|
|
|
# Process the CSV file
|
|
result, errors = _process_csv_file(file, mode='import')
|
|
if errors:
|
|
for error in errors:
|
|
flash(error, "error")
|
|
return redirect(request.url)
|
|
|
|
# Store entries in session for further processing
|
|
session['new_entries'] = result['new_entries']
|
|
session['invalid_entries'] = result['invalid_entries']
|
|
|
|
# Redirect to preview page
|
|
return render_template(
|
|
'csv_preview.html',
|
|
mode='import',
|
|
new_entries=result['new_entries'],
|
|
invalid_entries=result['invalid_entries'],
|
|
item_attributes=item_attributes,
|
|
brandingconfig=BrandingConfig
|
|
)
|
|
|
|
# Render the upload page for GET requests
|
|
return render_template('upload.html', mode="import", brandingconfig=BrandingConfig)
|
|
|
|
@upload_bp.route('/edit_using_csv/', methods=['GET', 'POST'])
|
|
@login_required
|
|
def edit_using_csv():
|
|
session['csv_mode'] = 'edit' # Store mode in session
|
|
if request.method == 'POST':
|
|
# Check if a file was uploaded
|
|
if 'file' not in request.files:
|
|
flash("No file uploaded.", "error")
|
|
return redirect(request.url)
|
|
|
|
file = request.files['file']
|
|
|
|
# Check if the file is a CSV
|
|
if file.filename == '' or not file.filename.endswith('.csv'):
|
|
flash("Please upload a valid CSV file.", "error")
|
|
return redirect(request.url)
|
|
|
|
# Process the CSV file
|
|
result, errors = _process_csv_file(file, mode='edit')
|
|
if errors:
|
|
for error in errors:
|
|
flash(error, "error")
|
|
return redirect(request.url)
|
|
|
|
# Store entries in session for further processing
|
|
session['existing_entries'] = result['existing_entries']
|
|
session['invalid_entries'] = result['invalid_entries']
|
|
|
|
# Redirect to preview page
|
|
return render_template(
|
|
'csv_preview.html',
|
|
mode='edit',
|
|
existing_entries=result['existing_entries'],
|
|
invalid_entries=result['invalid_entries'],
|
|
item_attributes=item_attributes,
|
|
brandingconfig=BrandingConfig
|
|
)
|
|
|
|
# Render the upload page for GET requests
|
|
return render_template('upload.html', mode="edit", brandingconfig=BrandingConfig) |