fixing field edits and adding custom fileds
This commit is contained in:
@@ -41,119 +41,264 @@ def index(tenant_id):
|
||||
return render_template('admin/index.html', products=products, tenant=tenant)
|
||||
|
||||
def add_product(tenant_id):
|
||||
# Get custom AR fields for this tenant
|
||||
custom_fields = database.get_custom_ar_fields(tenant_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
# Get form data
|
||||
product_id = request.form.get('product_id')
|
||||
name = request.form.get('name')
|
||||
price = request.form.get('price')
|
||||
|
||||
# Basic validation
|
||||
if not product_id or not name or not price:
|
||||
flash('Product ID, Name, and Price are required fields.')
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id)
|
||||
if not product_id:
|
||||
flash('Product ID is required.')
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id, custom_fields=custom_fields)
|
||||
|
||||
# Check if product ID already exists
|
||||
products = load_products(tenant_id)
|
||||
if product_id in products:
|
||||
flash('Product ID already exists.')
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id)
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id, custom_fields=custom_fields)
|
||||
|
||||
# Handle image upload
|
||||
# Handle backward compatibility image upload
|
||||
image_data = None
|
||||
image_mime_type = None
|
||||
image_path = f"/images/{product_id}.png" # Default path for display
|
||||
|
||||
if 'image' in request.files:
|
||||
file = request.files['image']
|
||||
if file and file.filename and allowed_file(file.filename):
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
image_path = f"/images/{product_id}.{extension}"
|
||||
|
||||
# Read image data
|
||||
image_data = file.read()
|
||||
|
||||
# Determine mime type
|
||||
mime_types = {
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
'gif': 'image/gif'
|
||||
}
|
||||
image_mime_type = mime_types.get(extension, 'image/jpeg')
|
||||
# Create product data structure based on custom fields
|
||||
product_data = []
|
||||
|
||||
# Create product data structure
|
||||
product_data = [
|
||||
{"fieldName": "_id", "label": "Item ID", "value": product_id, "editable": "false", "fieldType": "TEXT"},
|
||||
{"fieldName": "_name", "label": "Product Name", "value": name, "editable": "true", "fieldType": "TEXT"},
|
||||
{"fieldName": "_price", "label": "Sale Price", "value": f"${price}", "editable": "true", "fieldType": "TEXT"},
|
||||
{"fieldName": "_image", "label": "Image", "value": image_path, "editable": "false", "fieldType": "IMAGE_URI"}
|
||||
]
|
||||
# Always include _id field
|
||||
product_data.append({
|
||||
"fieldName": "_id",
|
||||
"label": "Item ID",
|
||||
"value": product_id,
|
||||
"editable": "false",
|
||||
"fieldType": "TEXT"
|
||||
})
|
||||
|
||||
# Process images after product is saved
|
||||
images_to_save = []
|
||||
|
||||
# Add other fields based on custom configuration
|
||||
for field in custom_fields:
|
||||
field_name = field['fieldName']
|
||||
if field_name == '_id':
|
||||
continue # Already added
|
||||
elif field['fieldType'] == 'IMAGE_URI':
|
||||
# Check if image was uploaded for this field
|
||||
image_field_name = f'image_{field_name}'
|
||||
if image_field_name in request.files:
|
||||
file = request.files[image_field_name]
|
||||
if file and file.filename and allowed_file(file.filename):
|
||||
# Read image data
|
||||
file.seek(0)
|
||||
img_data = file.read()
|
||||
|
||||
# Determine mime type
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
mime_types = {
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
'gif': 'image/gif'
|
||||
}
|
||||
mime_type = mime_types.get(extension, 'image/jpeg')
|
||||
|
||||
# Store for later saving
|
||||
images_to_save.append({
|
||||
'field_name': field_name,
|
||||
'data': img_data,
|
||||
'mime_type': mime_type
|
||||
})
|
||||
|
||||
# Set the image URL path
|
||||
image_path = f"/images/{product_id}_{field_name}.{extension}"
|
||||
|
||||
# For backward compatibility with _image field
|
||||
if field_name == '_image':
|
||||
image_data = img_data
|
||||
image_mime_type = mime_type
|
||||
else:
|
||||
image_path = ""
|
||||
else:
|
||||
image_path = ""
|
||||
|
||||
product_data.append({
|
||||
"fieldName": field_name,
|
||||
"label": field['label'],
|
||||
"value": image_path,
|
||||
"editable": field['editable'],
|
||||
"fieldType": field['fieldType']
|
||||
})
|
||||
else:
|
||||
# Get value from form
|
||||
value = request.form.get(f'field_{field_name}', '')
|
||||
product_data.append({
|
||||
"fieldName": field_name,
|
||||
"label": field['label'],
|
||||
"value": value,
|
||||
"editable": field['editable'],
|
||||
"fieldType": field['fieldType']
|
||||
})
|
||||
|
||||
# Also save fields that aren't in custom fields (for backward compatibility)
|
||||
if '_name' not in [f['fieldName'] for f in custom_fields]:
|
||||
name = request.form.get('name', '')
|
||||
if name:
|
||||
product_data.append({
|
||||
"fieldName": "_name",
|
||||
"label": "Product Name",
|
||||
"value": name,
|
||||
"editable": "true",
|
||||
"fieldType": "TEXT"
|
||||
})
|
||||
|
||||
if '_price' not in [f['fieldName'] for f in custom_fields]:
|
||||
price = request.form.get('price', '')
|
||||
if price:
|
||||
product_data.append({
|
||||
"fieldName": "_price",
|
||||
"label": "Sale Price",
|
||||
"value": f"${price}",
|
||||
"editable": "true",
|
||||
"fieldType": "TEXT"
|
||||
})
|
||||
|
||||
# Save to database
|
||||
database.save_product(product_id, tenant_id, product_data, image_data, image_mime_type)
|
||||
|
||||
# Save additional images
|
||||
for img in images_to_save:
|
||||
database.save_product_image(product_id, tenant_id, img['field_name'], img['data'], img['mime_type'])
|
||||
|
||||
flash('Product added successfully!')
|
||||
return redirect(url_for('admin.index', tenant_id=tenant_id))
|
||||
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id)
|
||||
return render_template('admin/add_product.html', tenant_id=tenant_id, custom_fields=custom_fields)
|
||||
|
||||
def edit_product(tenant_id, product_id):
|
||||
products = load_products(tenant_id)
|
||||
custom_fields = database.get_custom_ar_fields(tenant_id)
|
||||
|
||||
if product_id not in products:
|
||||
flash('Product not found.')
|
||||
return redirect(url_for('admin.index', tenant_id=tenant_id))
|
||||
|
||||
if request.method == 'POST':
|
||||
# Get form data
|
||||
name = request.form.get('name')
|
||||
price = request.form.get('price')
|
||||
|
||||
# Basic validation
|
||||
if not name or not price:
|
||||
flash('Name and Price are required fields.')
|
||||
return render_template('admin/edit_product.html', product_id=product_id, product=products[product_id], tenant_id=tenant_id)
|
||||
|
||||
# Update name and price
|
||||
for field in products[product_id]:
|
||||
if field["fieldName"] == "_name":
|
||||
field["value"] = name
|
||||
elif field["fieldName"] == "_price":
|
||||
field["value"] = f"${price}"
|
||||
|
||||
# Handle image upload
|
||||
# Handle backward compatibility image upload
|
||||
image_data = None
|
||||
image_mime_type = None
|
||||
|
||||
if 'image' in request.files and request.files['image'].filename:
|
||||
file = request.files['image']
|
||||
if allowed_file(file.filename):
|
||||
# Read new image data
|
||||
image_data = file.read()
|
||||
# Process images after product is saved
|
||||
images_to_save = []
|
||||
|
||||
# Update fields based on form data
|
||||
updated_product = []
|
||||
|
||||
# Always include _id field
|
||||
for field in products[product_id]:
|
||||
if field["fieldName"] == "_id":
|
||||
updated_product.append(field)
|
||||
break
|
||||
|
||||
# Process each custom field
|
||||
for custom_field in custom_fields:
|
||||
field_name = custom_field['fieldName']
|
||||
if field_name == '_id':
|
||||
continue
|
||||
|
||||
# Determine mime type
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
mime_types = {
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
'gif': 'image/gif'
|
||||
# Find existing field data
|
||||
existing_field = None
|
||||
for field in products[product_id]:
|
||||
if field["fieldName"] == field_name:
|
||||
existing_field = field.copy()
|
||||
break
|
||||
|
||||
if not existing_field:
|
||||
existing_field = {
|
||||
"fieldName": field_name,
|
||||
"label": custom_field['label'],
|
||||
"value": "",
|
||||
"editable": custom_field['editable'],
|
||||
"fieldType": custom_field['fieldType']
|
||||
}
|
||||
image_mime_type = mime_types.get(extension, 'image/jpeg')
|
||||
|
||||
# Update image path in product data
|
||||
image_path = f"/images/{product_id}.{extension}"
|
||||
|
||||
if custom_field['fieldType'] == 'IMAGE_URI':
|
||||
# Check if new image was uploaded
|
||||
image_field_name = f'image_{field_name}'
|
||||
if image_field_name in request.files and request.files[image_field_name].filename:
|
||||
file = request.files[image_field_name]
|
||||
if allowed_file(file.filename):
|
||||
# Read image data
|
||||
file.seek(0)
|
||||
img_data = file.read()
|
||||
|
||||
# Determine mime type
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
mime_types = {
|
||||
'jpg': 'image/jpeg',
|
||||
'jpeg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
'gif': 'image/gif'
|
||||
}
|
||||
mime_type = mime_types.get(extension, 'image/jpeg')
|
||||
|
||||
# Store for later saving
|
||||
images_to_save.append({
|
||||
'field_name': field_name,
|
||||
'data': img_data,
|
||||
'mime_type': mime_type
|
||||
})
|
||||
|
||||
# Update image path
|
||||
existing_field["value"] = f"/images/{product_id}_{field_name}.{extension}"
|
||||
|
||||
# For backward compatibility with _image field
|
||||
if field_name == '_image':
|
||||
image_data = img_data
|
||||
image_mime_type = mime_type
|
||||
else:
|
||||
# Get value from form
|
||||
value = request.form.get(f'field_{field_name}', '')
|
||||
if field_name == '_price' and value and not value.startswith('$'):
|
||||
value = f"${value}"
|
||||
existing_field["value"] = value
|
||||
|
||||
updated_product.append(existing_field)
|
||||
|
||||
# Handle backward compatibility fields
|
||||
if '_name' not in [f['fieldName'] for f in custom_fields]:
|
||||
name = request.form.get('name', '')
|
||||
if name:
|
||||
for field in products[product_id]:
|
||||
if field["fieldName"] == "_image":
|
||||
field["value"] = image_path
|
||||
if field["fieldName"] == "_name":
|
||||
field["value"] = name
|
||||
updated_product.append(field)
|
||||
break
|
||||
|
||||
if '_price' not in [f['fieldName'] for f in custom_fields]:
|
||||
price = request.form.get('price', '')
|
||||
if price:
|
||||
for field in products[product_id]:
|
||||
if field["fieldName"] == "_price":
|
||||
field["value"] = f"${price}"
|
||||
updated_product.append(field)
|
||||
break
|
||||
|
||||
# Save to database
|
||||
database.save_product(product_id, tenant_id, products[product_id], image_data, image_mime_type)
|
||||
database.save_product(product_id, tenant_id, updated_product, image_data, image_mime_type)
|
||||
|
||||
# Save additional images
|
||||
for img in images_to_save:
|
||||
database.save_product_image(product_id, tenant_id, img['field_name'], img['data'], img['mime_type'])
|
||||
|
||||
flash('Product updated successfully!')
|
||||
return redirect(url_for('admin.index', tenant_id=tenant_id))
|
||||
|
||||
return render_template('admin/edit_product.html', product_id=product_id, product=products[product_id], tenant_id=tenant_id)
|
||||
return render_template('admin/edit_product.html',
|
||||
product_id=product_id,
|
||||
product=products[product_id],
|
||||
tenant_id=tenant_id,
|
||||
custom_fields=custom_fields)
|
||||
|
||||
def delete_product(tenant_id, product_id):
|
||||
products = load_products(tenant_id)
|
||||
@@ -245,3 +390,64 @@ def manage_credentials(tenant_id):
|
||||
flash('Username and password are required.')
|
||||
|
||||
return render_template('admin/credentials.html', tenant=tenant, tenant_id=tenant_id)
|
||||
|
||||
def manage_ar_fields(tenant_id):
|
||||
"""Manage custom AR content fields"""
|
||||
tenant = database.get_or_create_tenant(tenant_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
action = request.form.get('action')
|
||||
|
||||
if action == 'add':
|
||||
field_data = {
|
||||
'fieldName': request.form.get('fieldName'),
|
||||
'label': request.form.get('label'),
|
||||
'fieldType': request.form.get('fieldType'),
|
||||
'editable': request.form.get('editable', 'true'),
|
||||
'displayOrder': int(request.form.get('displayOrder', 0))
|
||||
}
|
||||
|
||||
if field_data['fieldName'] and field_data['label']:
|
||||
database.save_custom_ar_field(tenant_id, field_data)
|
||||
flash('Custom field added successfully!')
|
||||
else:
|
||||
flash('Field name and label are required.')
|
||||
|
||||
elif action == 'delete':
|
||||
field_id = request.form.get('field_id')
|
||||
if field_id:
|
||||
database.delete_custom_ar_field(tenant_id, int(field_id))
|
||||
flash('Custom field deleted successfully!')
|
||||
|
||||
elif action == 'update':
|
||||
field_data = {
|
||||
'id': int(request.form.get('field_id')),
|
||||
'fieldName': request.form.get('fieldName'),
|
||||
'label': request.form.get('label'),
|
||||
'fieldType': request.form.get('fieldType'),
|
||||
'editable': request.form.get('editable', 'true'),
|
||||
'displayOrder': int(request.form.get('displayOrder', 0))
|
||||
}
|
||||
|
||||
if field_data['fieldName'] and field_data['label']:
|
||||
database.save_custom_ar_field(tenant_id, field_data)
|
||||
flash('Custom field updated successfully!')
|
||||
else:
|
||||
flash('Field name and label are required.')
|
||||
|
||||
return redirect(url_for('admin.manage_ar_fields', tenant_id=tenant_id))
|
||||
|
||||
# Get existing custom fields
|
||||
custom_fields = database.get_custom_ar_fields(tenant_id)
|
||||
|
||||
# Available field types
|
||||
field_types = [
|
||||
'TEXT',
|
||||
'IMAGE_URI'
|
||||
]
|
||||
|
||||
return render_template('admin/ar_fields.html',
|
||||
tenant=tenant,
|
||||
tenant_id=tenant_id,
|
||||
custom_fields=custom_fields,
|
||||
field_types=field_types)
|
||||
|
||||
Reference in New Issue
Block a user