Update menu.py
Browse files
menu.py
CHANGED
@@ -22,7 +22,7 @@ SECTION_ORDER = ["Best Sellers", "Starters", "Biryanis", "Curries", "Breads", "C
|
|
22 |
# Create placeholder video at startup if it doesn't exist
|
23 |
if not os.path.exists(PLACEHOLDER_PATH):
|
24 |
with open(PLACEHOLDER_PATH, 'wb') as f:
|
25 |
-
f.
|
26 |
logger.info(f"Created placeholder video at {PLACEHOLDER_PATH}")
|
27 |
|
28 |
def get_valid_video_path(item_name, video_url=None):
|
@@ -36,7 +36,7 @@ def get_valid_video_path(item_name, video_url=None):
|
|
36 |
return f"https://biryanihub-dev-ed.develop.my.salesforce.com/sfc/servlet.shepherd/version/download/{video_url}"
|
37 |
if not os.path.exists(PLACEHOLDER_PATH):
|
38 |
with open(PLACEHOLDER_PATH, 'wb') as f:
|
39 |
-
f.
|
40 |
logger.info(f"Created missing placeholder video at {PLACEHOLDER_PATH}")
|
41 |
return f"/static/{PLACEHOLDER_VIDEO}"
|
42 |
|
@@ -56,9 +56,9 @@ def menu():
|
|
56 |
else:
|
57 |
return redirect(url_for("login"))
|
58 |
else:
|
59 |
-
user_name = session.get('user_name'
|
60 |
|
61 |
-
first_letter = user_name[0].upper() if user_name
|
62 |
user_image = session.get('user_image')
|
63 |
|
64 |
# Check if Avatar__c field exists on Customer_Login__c
|
@@ -74,7 +74,7 @@ def menu():
|
|
74 |
query_fields = ["Id", "Referral__c", "Reward_Points__c"]
|
75 |
if avatar_field_exists:
|
76 |
query_fields.append("Avatar__c")
|
77 |
-
user_query = f"SELECT {', '.join(query_fields)} FROM Customer_Login__c WHERE Email__c = '{user_email}'
|
78 |
|
79 |
# Fetch user referral and reward points
|
80 |
try:
|
@@ -82,11 +82,11 @@ def menu():
|
|
82 |
if not user_result.get('records'):
|
83 |
logger.warning(f"No user found with email: {user_email}")
|
84 |
return redirect(url_for('login'))
|
85 |
-
user_record = user_result['records'][0]
|
86 |
except Exception as e:
|
87 |
logger.error(f"Error querying user data: {str(e)}")
|
88 |
return jsonify({"success": False, "error": "Failed to fetch user data from Salesforce"}), 500
|
89 |
|
|
|
90 |
user_id = user_record['Id']
|
91 |
referral_code = user_record.get('Referral__c', 'N/A')
|
92 |
reward_points = user_record.get('Reward_Points__c', 0)
|
@@ -133,7 +133,7 @@ def menu():
|
|
133 |
# Fetch all Custom_Dish__c records with only existing fields
|
134 |
custom_dish_query = """
|
135 |
SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
|
136 |
-
Veg_NonVeg__c, Section__c, Total_Ordered__c
|
137 |
FROM Custom_Dish__c
|
138 |
WHERE CreatedDate >= LAST_N_DAYS:7
|
139 |
"""
|
@@ -150,9 +150,6 @@ def menu():
|
|
150 |
item['Video1__c'] = get_valid_video_path(item['Name'])
|
151 |
item['Section__c'] = item.get('Section__c', "Customized dish")
|
152 |
item['Description__c'] = item.get('Description__c', "No description available")
|
153 |
-
item['IngredientsInfo__c'] = item.get('Ingredients__c', "Not specified") # Map Ingredients__c to IngredientsInfo__c
|
154 |
-
item['NutritionalInfo__c'] = "Not available" # Custom dishes may not have this
|
155 |
-
item['Allergens__c'] = "None listed" # Default for custom dishes
|
156 |
item['is_menu_item'] = False
|
157 |
|
158 |
# Merge all items
|
@@ -160,7 +157,7 @@ def menu():
|
|
160 |
ordered_menu = {section: [] for section in SECTION_ORDER}
|
161 |
|
162 |
# Process best sellers
|
163 |
-
best_sellers = sorted(all_items, key=lambda x: x
|
164 |
if selected_category == "Veg":
|
165 |
best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Veg", "both"]]
|
166 |
elif selected_category == "Non veg":
|
@@ -202,7 +199,7 @@ def menu():
|
|
202 |
cart_item_count=cart_item_count,
|
203 |
user_image=user_image,
|
204 |
user_id=user_id,
|
205 |
-
highlight_item=highlight_item
|
206 |
)
|
207 |
|
208 |
@menu_blueprint.route('/search', methods=['GET'])
|
@@ -211,8 +208,8 @@ def search():
|
|
211 |
if not user_email:
|
212 |
return redirect(url_for("login"))
|
213 |
|
214 |
-
user_name = session.get('user_name'
|
215 |
-
first_letter = user_name[0].upper() if user_name
|
216 |
user_image = session.get('user_image')
|
217 |
|
218 |
# Get cart item count
|
@@ -251,7 +248,7 @@ def search():
|
|
251 |
# Fetch all Custom_Dish__c records
|
252 |
custom_dish_query = """
|
253 |
SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
|
254 |
-
Veg_NonVeg__c, Section__c, Total_Ordered__c
|
255 |
FROM Custom_Dish__c
|
256 |
WHERE CreatedDate >= LAST_N_DAYS:7
|
257 |
"""
|
@@ -267,9 +264,6 @@ def search():
|
|
267 |
item['Video1__c'] = get_valid_video_path(item['Name'])
|
268 |
item['Section__c'] = item.get('Section__c', "Customized dish")
|
269 |
item['Description__c'] = item.get('Description__c', "No description available")
|
270 |
-
item['IngredientsInfo__c'] = item.get('Ingredients__c', "Not specified") # Map Ingredients__c to IngredientsInfo__c
|
271 |
-
item['NutritionalInfo__c'] = "Not available" # Custom dishes may not have this
|
272 |
-
item['Allergens__c'] = "None listed" # Default for custom dishes
|
273 |
item['is_menu_item'] = False
|
274 |
|
275 |
all_items = food_items + custom_dishes
|
@@ -320,7 +314,7 @@ def upload_avatar():
|
|
320 |
user_email = session.get('user_email')
|
321 |
if user_email:
|
322 |
try:
|
323 |
-
user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'
|
324 |
user_result = sf.query(user_query)
|
325 |
if user_result.get('records'):
|
326 |
user_id = user_result['records'][0]['Id']
|
@@ -355,7 +349,7 @@ def delete_avatar():
|
|
355 |
logger.info("Image removed from session")
|
356 |
|
357 |
try:
|
358 |
-
user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'
|
359 |
user_result = sf.query(user_query)
|
360 |
if user_result.get('records'):
|
361 |
user_id = user_result['records'][0]['Id']
|
@@ -389,7 +383,7 @@ def get_addons():
|
|
389 |
query = f"""
|
390 |
SELECT Name, Customization_Type__c, Options__c, Max_Selections__c, Extra_Charge__c, Extra_Charge_Amount__c
|
391 |
FROM Customization_Options__c
|
392 |
-
WHERE Section__c = '{item_section}'
|
393 |
"""
|
394 |
result = sf.query_all(query)
|
395 |
addons = result.get('records', [])
|
@@ -400,14 +394,14 @@ def get_addons():
|
|
400 |
formatted_addons = []
|
401 |
for addon in addons:
|
402 |
options = addon.get("Options__c", "")
|
403 |
-
options =
|
404 |
formatted_addons.append({
|
405 |
"name": addon.get("Name", ""),
|
406 |
"type": addon.get("Customization_Type__c", ""),
|
407 |
"options": options,
|
408 |
-
"max_selections":
|
409 |
-
"extra_charge":
|
410 |
-
"extra_charge_amount":
|
411 |
})
|
412 |
|
413 |
return jsonify({"success": True, "addons": formatted_addons})
|
@@ -420,10 +414,6 @@ def get_addons():
|
|
420 |
def add_to_cart():
|
421 |
try:
|
422 |
data = request.json
|
423 |
-
if not data:
|
424 |
-
logger.error("No data provided in request")
|
425 |
-
return jsonify({"success": False, "error": "No data provided"}), 400
|
426 |
-
|
427 |
item_name = data.get('itemName', '').strip()
|
428 |
item_price = float(data.get('itemPrice', 0))
|
429 |
item_image = data.get('itemImage', '')
|
@@ -441,19 +431,17 @@ def add_to_cart():
|
|
441 |
# Sanitize inputs to prevent SOQL injection
|
442 |
item_name = item_name.replace("'", "''")
|
443 |
customer_email = customer_email.replace("'", "''")
|
444 |
-
instructions = instructions.replace("'", "''")
|
445 |
|
446 |
query = f"""
|
447 |
SELECT Id, Quantity__c, Add_Ons__c, Add_Ons_Price__c, Instructions__c, Price__c
|
448 |
FROM Cart_Item__c
|
449 |
WHERE Customer_Email__c = '{customer_email}' AND Name = '{item_name}'
|
450 |
-
LIMIT 1
|
451 |
"""
|
452 |
result = sf.query(query)
|
453 |
cart_items = result.get("records", [])
|
454 |
|
455 |
-
addons_price = sum(float(addon.get('price', 0)) for addon in addons
|
456 |
-
new_addons = "; ".join([f"{addon['name']} (${addon['price']})" for addon in addons
|
457 |
|
458 |
if cart_items:
|
459 |
cart_item = cart_items[0]
|
@@ -471,8 +459,10 @@ def add_to_cart():
|
|
471 |
if instructions:
|
472 |
combined_instructions = f"{combined_instructions} | {instructions}".strip(" | ")
|
473 |
|
474 |
-
combined_addons_list =
|
475 |
-
combined_addons_price = sum(
|
|
|
|
|
476 |
|
477 |
total_price = (existing_quantity + quantity) * item_price + combined_addons_price
|
478 |
|
@@ -504,7 +494,7 @@ def add_to_cart():
|
|
504 |
# Fetch updated cart for UI update
|
505 |
cart_query = f"SELECT Name, Quantity__c FROM Cart_Item__c WHERE Customer_Email__c = '{customer_email}'"
|
506 |
cart_result = sf.query_all(cart_query)
|
507 |
-
cart = [{"itemName": item["Name"], "quantity":
|
508 |
|
509 |
logger.info(f"Item '{item_name}' added to cart for {customer_email}")
|
510 |
return jsonify({"success": True, "message": "Item added to cart successfully.", "cart": cart})
|
@@ -516,60 +506,4 @@ def add_to_cart():
|
|
516 |
logger.error(f"Error adding item to cart: {str(e)}", exc_info=True)
|
517 |
return jsonify({"success": False, "error": f"An error occurred while adding the item to the cart: {str(e)}"}), 500
|
518 |
|
519 |
-
@menu_blueprint.route('/customdish/generate_custom_dish', methods=['POST'])
|
520 |
-
def generate_custom_dish():
|
521 |
-
try:
|
522 |
-
# Get data from the request
|
523 |
-
data = request.form
|
524 |
-
name = data.get('name', '').strip()
|
525 |
-
ingredients = data.get('ingredients', '').strip()
|
526 |
-
description = data.get('description', '').strip()
|
527 |
-
price = float(data.get('price', 0))
|
528 |
-
|
529 |
-
# Validate inputs
|
530 |
-
if not all([name, ingredients, description]) or price <= 0:
|
531 |
-
logger.error(f"Invalid custom dish data: name={name}, ingredients={ingredients}, description={description}, price={price}")
|
532 |
-
return jsonify({"success": False, "error": "All fields are required and price must be positive."}), 400
|
533 |
-
|
534 |
-
# Sanitize inputs to prevent SOQL injection
|
535 |
-
name = name.replace("'", "''")
|
536 |
-
ingredients = ingredients.replace("'", "''")
|
537 |
-
description = description.replace("'", "''")
|
538 |
-
|
539 |
-
# Get user information
|
540 |
-
customer_email = session.get('user_email')
|
541 |
-
if not customer_email:
|
542 |
-
logger.error("No user email in session")
|
543 |
-
return jsonify({"success": False, "error": "User not authenticated"}), 401
|
544 |
-
|
545 |
-
# Create custom dish in Salesforce
|
546 |
-
custom_dish_data = {
|
547 |
-
"Name": name,
|
548 |
-
"Price__c": price,
|
549 |
-
"Description__c": description,
|
550 |
-
"Ingredients__c": ingredients,
|
551 |
-
"Customer_Email__c": customer_email,
|
552 |
-
"Section__c": "Customized dish",
|
553 |
-
"Veg_NonVeg__c": data.get('veg_nonveg', 'Veg'), # Allow frontend to specify
|
554 |
-
"Total_Ordered__c": 0
|
555 |
-
}
|
556 |
-
|
557 |
-
# Validate required Salesforce fields
|
558 |
-
required_fields = ['Name', 'Price__c', 'Description__c', 'Ingredients__c', 'Customer_Email__c', 'Section__c']
|
559 |
-
if not all(field in custom_dish_data for field in required_fields):
|
560 |
-
logger.error(f"Missing required fields in custom_dish_data: {custom_dish_data}")
|
561 |
-
return jsonify({"success": False, "error": "Missing required fields for custom dish creation"}), 400
|
562 |
-
|
563 |
-
sf.Custom_Dish__c.create(custom_dish_data)
|
564 |
-
logger.info(f"Custom dish '{name}' created for {customer_email}")
|
565 |
-
|
566 |
-
return jsonify({"success": True, "message": "Custom dish submitted successfully."})
|
567 |
-
|
568 |
-
except ValueError as e:
|
569 |
-
logger.error(f"Invalid data format in custom dish submission: {str(e)}")
|
570 |
-
return jsonify({"success": False, "error": f"Invalid data format: {str(e)}"}), 400
|
571 |
-
except Exception as e:
|
572 |
-
logger.error(f"Error creating custom dish: {str(e)}", exc_info=True)
|
573 |
-
return jsonify({"success": False, "error": f"Server error: {str(e)}. Data saved locally on client."}), 500
|
574 |
-
|
575 |
# Note: Ensure 'login' route exists in your app or adjust redirect accordingly
|
|
|
22 |
# Create placeholder video at startup if it doesn't exist
|
23 |
if not os.path.exists(PLACEHOLDER_PATH):
|
24 |
with open(PLACEHOLDER_PATH, 'wb') as f:
|
25 |
+
f.close()
|
26 |
logger.info(f"Created placeholder video at {PLACEHOLDER_PATH}")
|
27 |
|
28 |
def get_valid_video_path(item_name, video_url=None):
|
|
|
36 |
return f"https://biryanihub-dev-ed.develop.my.salesforce.com/sfc/servlet.shepherd/version/download/{video_url}"
|
37 |
if not os.path.exists(PLACEHOLDER_PATH):
|
38 |
with open(PLACEHOLDER_PATH, 'wb') as f:
|
39 |
+
f.close()
|
40 |
logger.info(f"Created missing placeholder video at {PLACEHOLDER_PATH}")
|
41 |
return f"/static/{PLACEHOLDER_VIDEO}"
|
42 |
|
|
|
56 |
else:
|
57 |
return redirect(url_for("login"))
|
58 |
else:
|
59 |
+
user_name = session.get('user_name')
|
60 |
|
61 |
+
first_letter = user_name[0].upper() if user_name else "A"
|
62 |
user_image = session.get('user_image')
|
63 |
|
64 |
# Check if Avatar__c field exists on Customer_Login__c
|
|
|
74 |
query_fields = ["Id", "Referral__c", "Reward_Points__c"]
|
75 |
if avatar_field_exists:
|
76 |
query_fields.append("Avatar__c")
|
77 |
+
user_query = f"SELECT {', '.join(query_fields)} FROM Customer_Login__c WHERE Email__c = '{user_email}'"
|
78 |
|
79 |
# Fetch user referral and reward points
|
80 |
try:
|
|
|
82 |
if not user_result.get('records'):
|
83 |
logger.warning(f"No user found with email: {user_email}")
|
84 |
return redirect(url_for('login'))
|
|
|
85 |
except Exception as e:
|
86 |
logger.error(f"Error querying user data: {str(e)}")
|
87 |
return jsonify({"success": False, "error": "Failed to fetch user data from Salesforce"}), 500
|
88 |
|
89 |
+
user_record = user_result['records'][0]
|
90 |
user_id = user_record['Id']
|
91 |
referral_code = user_record.get('Referral__c', 'N/A')
|
92 |
reward_points = user_record.get('Reward_Points__c', 0)
|
|
|
133 |
# Fetch all Custom_Dish__c records with only existing fields
|
134 |
custom_dish_query = """
|
135 |
SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
|
136 |
+
Veg_NonVeg__c, Section__c, Total_Ordered__c
|
137 |
FROM Custom_Dish__c
|
138 |
WHERE CreatedDate >= LAST_N_DAYS:7
|
139 |
"""
|
|
|
150 |
item['Video1__c'] = get_valid_video_path(item['Name'])
|
151 |
item['Section__c'] = item.get('Section__c', "Customized dish")
|
152 |
item['Description__c'] = item.get('Description__c', "No description available")
|
|
|
|
|
|
|
153 |
item['is_menu_item'] = False
|
154 |
|
155 |
# Merge all items
|
|
|
157 |
ordered_menu = {section: [] for section in SECTION_ORDER}
|
158 |
|
159 |
# Process best sellers
|
160 |
+
best_sellers = sorted(all_items, key=lambda x: x['Total_Ordered__c'], reverse=True)
|
161 |
if selected_category == "Veg":
|
162 |
best_sellers = [item for item in best_sellers if item.get("Veg_NonVeg__c") in ["Veg", "both"]]
|
163 |
elif selected_category == "Non veg":
|
|
|
199 |
cart_item_count=cart_item_count,
|
200 |
user_image=user_image,
|
201 |
user_id=user_id,
|
202 |
+
highlight_item=highlight_item # Pass the item to highlight to the template
|
203 |
)
|
204 |
|
205 |
@menu_blueprint.route('/search', methods=['GET'])
|
|
|
208 |
if not user_email:
|
209 |
return redirect(url_for("login"))
|
210 |
|
211 |
+
user_name = session.get('user_name')
|
212 |
+
first_letter = user_name[0].upper() if user_name else "A"
|
213 |
user_image = session.get('user_image')
|
214 |
|
215 |
# Get cart item count
|
|
|
248 |
# Fetch all Custom_Dish__c records
|
249 |
custom_dish_query = """
|
250 |
SELECT Name, Price__c, Description__c, Image1__c, Image2__c,
|
251 |
+
Veg_NonVeg__c, Section__c, Total_Ordered__c
|
252 |
FROM Custom_Dish__c
|
253 |
WHERE CreatedDate >= LAST_N_DAYS:7
|
254 |
"""
|
|
|
264 |
item['Video1__c'] = get_valid_video_path(item['Name'])
|
265 |
item['Section__c'] = item.get('Section__c', "Customized dish")
|
266 |
item['Description__c'] = item.get('Description__c', "No description available")
|
|
|
|
|
|
|
267 |
item['is_menu_item'] = False
|
268 |
|
269 |
all_items = food_items + custom_dishes
|
|
|
314 |
user_email = session.get('user_email')
|
315 |
if user_email:
|
316 |
try:
|
317 |
+
user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'"
|
318 |
user_result = sf.query(user_query)
|
319 |
if user_result.get('records'):
|
320 |
user_id = user_result['records'][0]['Id']
|
|
|
349 |
logger.info("Image removed from session")
|
350 |
|
351 |
try:
|
352 |
+
user_query = f"SELECT Id FROM Customer_Login__c WHERE Email__c = '{user_email}'"
|
353 |
user_result = sf.query(user_query)
|
354 |
if user_result.get('records'):
|
355 |
user_id = user_result['records'][0]['Id']
|
|
|
383 |
query = f"""
|
384 |
SELECT Name, Customization_Type__c, Options__c, Max_Selections__c, Extra_Charge__c, Extra_Charge_Amount__c
|
385 |
FROM Customization_Options__c
|
386 |
+
WHERE Section__c = '{item_section}'
|
387 |
"""
|
388 |
result = sf.query_all(query)
|
389 |
addons = result.get('records', [])
|
|
|
394 |
formatted_addons = []
|
395 |
for addon in addons:
|
396 |
options = addon.get("Options__c", "")
|
397 |
+
options = options.split(", ") if options else []
|
398 |
formatted_addons.append({
|
399 |
"name": addon.get("Name", ""),
|
400 |
"type": addon.get("Customization_Type__c", ""),
|
401 |
"options": options,
|
402 |
+
"max_selections": addon.get("Max_Selections__c", 1),
|
403 |
+
"extra_charge": addon.get("Extra_Charge__c", False),
|
404 |
+
"extra_charge_amount": addon.get("Extra_Charge_Amount__c", 0)
|
405 |
})
|
406 |
|
407 |
return jsonify({"success": True, "addons": formatted_addons})
|
|
|
414 |
def add_to_cart():
|
415 |
try:
|
416 |
data = request.json
|
|
|
|
|
|
|
|
|
417 |
item_name = data.get('itemName', '').strip()
|
418 |
item_price = float(data.get('itemPrice', 0))
|
419 |
item_image = data.get('itemImage', '')
|
|
|
431 |
# Sanitize inputs to prevent SOQL injection
|
432 |
item_name = item_name.replace("'", "''")
|
433 |
customer_email = customer_email.replace("'", "''")
|
|
|
434 |
|
435 |
query = f"""
|
436 |
SELECT Id, Quantity__c, Add_Ons__c, Add_Ons_Price__c, Instructions__c, Price__c
|
437 |
FROM Cart_Item__c
|
438 |
WHERE Customer_Email__c = '{customer_email}' AND Name = '{item_name}'
|
|
|
439 |
"""
|
440 |
result = sf.query(query)
|
441 |
cart_items = result.get("records", [])
|
442 |
|
443 |
+
addons_price = sum(float(addon.get('price', 0)) for addon in addons)
|
444 |
+
new_addons = "; ".join([f"{addon['name']} (${addon['price']})" for addon in addons]) if addons else "None"
|
445 |
|
446 |
if cart_items:
|
447 |
cart_item = cart_items[0]
|
|
|
459 |
if instructions:
|
460 |
combined_instructions = f"{combined_instructions} | {instructions}".strip(" | ")
|
461 |
|
462 |
+
combined_addons_list = combined_addons.split("; ")
|
463 |
+
combined_addons_price = sum(
|
464 |
+
float(addon.split("($")[1][:-1]) for addon in combined_addons_list if "($" in addon
|
465 |
+
)
|
466 |
|
467 |
total_price = (existing_quantity + quantity) * item_price + combined_addons_price
|
468 |
|
|
|
494 |
# Fetch updated cart for UI update
|
495 |
cart_query = f"SELECT Name, Quantity__c FROM Cart_Item__c WHERE Customer_Email__c = '{customer_email}'"
|
496 |
cart_result = sf.query_all(cart_query)
|
497 |
+
cart = [{"itemName": item["Name"], "quantity": item["Quantity__c"]} for item in cart_result.get("records", [])]
|
498 |
|
499 |
logger.info(f"Item '{item_name}' added to cart for {customer_email}")
|
500 |
return jsonify({"success": True, "message": "Item added to cart successfully.", "cart": cart})
|
|
|
506 |
logger.error(f"Error adding item to cart: {str(e)}", exc_info=True)
|
507 |
return jsonify({"success": False, "error": f"An error occurred while adding the item to the cart: {str(e)}"}), 500
|
508 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
509 |
# Note: Ensure 'login' route exists in your app or adjust redirect accordingly
|